package cn.net.cpzslibs.prot;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import cn.net.cpzslibs.address.AddressUtil;

public class Prot13QueryCount extends ProtBase {

	private final short iTaskCode13 = 13;
	private final short iTaskCode1301 = 1301;
	private final short iTaskCode1302 = 1302;
	/**
	 * 消费信息 （合并13,14协议）
	 */
	private final short iTaskCode1303 = 1303;
	/**
	 * 消费信息 （汽配，合并13,14协议）
	 */
	private final short iTaskCode1304 = 1304;
	/**
	 * 替代1302协议，稽查使用，只对数据进行查询
	 */
	private final short iTaskCode1305 = 1305;
	/**
	 * 酒类消费
	 */
	private final short iTaskCode1306 = 1306;
	/**
	 * 终端系统类型 1000：IOS;终端 2000：Android终端; 3000：Web终端; 4000：电话;5000:微信wap
	 */
	private final short imTerminalType = 2000;

	/********************* 以下为暴露出来的数据 *****************************/
	/**
	 * 首次查询时间
	 */
	private long iFirstQueryTime;
	/**
	 * 消费查询次数
	 */
	private int iConsCount;
	/**
	 * 消费:第一次消费地址
	 */
	private int iFirstConsAreaCode;
	/**
	 * 消费:第一次消费时间
	 */
	private long iFirstConsTime;

	/* .********************封装，自动判断类型 ************************************* */
	/**
	 * 查询消费次数，不修改数据库数据 <br/>
	 * 2015-5-25下午3:37:09
	 * 
	 * @param socketCreate
	 * @throws IOException
	 */
	public void dealQueryCountSwitch(SocketCreate socketCreate)
			throws IOException {
		switch (socketCreate.getiWorkStyle()) {
		case WorkType.Car:
			dealQueryCountCar1304(socketCreate);
			break;
		case WorkType.Wine:
			dealQueryCountWine1306(socketCreate);
			break;
		default:
			dealQueryCount1303(socketCreate);
			break;
		}
	}

	/**
	 * 查询消费次数，并且修改数据库数据 <br/>
	 * 2015-5-25下午3:43:30
	 * 
	 * @param socketCreate
	 * @throws IOException
	 */
	public void dealConsCountSwitch(SocketCreate socketCreate, int iConsArea,
                                    short iConsCheckCode) throws IOException {
		switch (socketCreate.getiWorkStyle()) {
		case WorkType.Car:
			dealCarConsInfo1304(socketCreate, iConsArea, iConsCheckCode);
			break;
		case WorkType.Wine:
			dealWineConsInfo1306(socketCreate, iConsArea, iConsCheckCode);
			break;
		default:
			dealFirstConsInfo1303(socketCreate, iConsArea, iConsCheckCode);
			break;
		}
	}

	/********************* 1303**1304**1305**1306 **************************************/
	/**
	 * 1303查询次数，增加服务器上的查询的次数 <br/>
	 * 扫描后使用该协议<br/>
	 * 2015-4-13上午10:29:23
	 * 
	 * @param socketCreate
	 * @throws IOException
	 */
	public void dealQueryCount1303(SocketCreate socketCreate)
			throws IOException {
		int iConsArea = 0;
		short iConsCheckCode = 0;
		dealFirstConsInfo1303(socketCreate, iConsArea, iConsCheckCode);
	}

	/**
	 * 1303.替换13号和14号协议 <br/>
	 * 2015-4-10下午4:29:58
	 * 
	 * @param iConsArea
	 *            消费地区
	 * @param iConsCheckCode
	 *            消费码
	 * @throws IOException
	 */
	public void dealFirstConsInfo1303(SocketCreate socketCreate, int iConsArea,
                                      short iConsCheckCode) throws IOException {

		this.iSendTaskIndex = socketCreate.getiTaskIndex();
		short iTaskCode = this.iTaskCode1303;
		recProt_ConsInfo(socketCreate.getDis(), socketCreate.getDos(),
				iTaskCode, socketCreate.getiLabel(), iConsArea, iConsCheckCode);
	}

	/**
	 * 1304.汽配模式使用,只是查询次数，不改变数据库协议<br/>
	 * 消费地区,消费码均为0<br/>
	 * 替换1301号和14号协议 <br/>
	 * 2015-4-10下午4:29:58
	 * 
	 * @param socketCreate
	 * @throws IOException
	 */
	public void dealQueryCountCar1304(SocketCreate socketCreate)
			throws IOException {
		int iConsArea = 0;
		short iConsCheckCode = 0;
		dealCarConsInfo1304(socketCreate, iConsArea, iConsCheckCode);
	}

	/**
	 * 1304.汽配模式使用<br/>
	 * 替换1301号和14号协议 <br/>
	 * 2015-4-10下午4:29:58
	 * 
	 * @param iConsArea
	 *            消费地区
	 * @param iConsCheckCode
	 *            消费码
	 * @throws IOException
	 */
	public void dealCarConsInfo1304(SocketCreate socketCreate, int iConsArea,
                                    short iConsCheckCode) throws IOException {

		this.iSendTaskIndex = socketCreate.getiTaskIndex();
		short iTaskCode = this.iTaskCode1304;
		recProt_ConsInfo(socketCreate.getDis(), socketCreate.getDos(),
				iTaskCode, socketCreate.getiLabel(), iConsArea, iConsCheckCode);
	}

	/**
	 * 1305.稽查使用<br/>
	 * 替换1301号和14号协议 <br/>
	 * 2015-4-14下午3:26:43
	 * 
	 * @param dis
	 * @param dos
	 * @param iLabel
	 *            追溯码
	 * @throws IOException
	 */
	public void dealCheckConsInfo1305(SocketCreate socketCreate)
			throws IOException {

		this.iSendTaskIndex = socketCreate.getiTaskIndex();
		short iTaskCode = this.iTaskCode1305;
		int iConsArea = 0;
		short iConsCheckCode = 0;
		recProt_ConsInfo(socketCreate.getDis(), socketCreate.getDos(),
				iTaskCode, socketCreate.getiLabel(), iConsArea, iConsCheckCode);
	}
	public void dealCheckConsInfo1305(SocketCreate socketCreate, long labelId)
			throws IOException {

		this.iSendTaskIndex = socketCreate.getiTaskIndex();
//		this.iSendTaskIndex = 0;
		short iTaskCode = this.iTaskCode1305;
		int iConsArea = 0;
		short iConsCheckCode = 0;
		recProt_ConsInfo(socketCreate.getDis(), socketCreate.getDos(),
				iTaskCode, labelId, iConsArea, iConsCheckCode);
	}

	/**
	 * 1306.酒类使用,只是查询次数，不改变数据库协议 <br/>
	 * 消费地区,消费码均为0<br/>
	 * 2015-4-30下午1:29:55
	 * 
	 * @param socketCreate
	 * @throws IOException
	 */
	public void dealQueryCountWine1306(SocketCreate socketCreate)
			throws IOException {
		int iConsArea = 0;
		short iConsCheckCode = 0;
		dealWineConsInfo1306(socketCreate, iConsArea, iConsCheckCode);
	}

	/**
	 * 1306.酒类使用 <br/>
	 * 2015-4-30下午1:29:55
	 * 
	 * @param socketCreate
	 * @param iConsArea
	 * @param iConsCheckCode
	 * @throws IOException
	 */
	public void dealWineConsInfo1306(SocketCreate socketCreate, int iConsArea,
                                     short iConsCheckCode) throws IOException {
		this.iSendTaskIndex = socketCreate.getiTaskIndex();
		short iTaskCode = this.iTaskCode1306;
		recProt_ConsInfo(socketCreate.getDis(), socketCreate.getDos(),
				iTaskCode, socketCreate.getiLabel(), iConsArea, iConsCheckCode);
	}

	/**
	 * 1303和1304,1306使用的发送协议 <br/>
	 * 2015-4-10下午3:55:29
	 * 
	 * @param dos
	 * @param iTaskCode
	 *            任务号
	 * @param iLabel
	 *            标签Id
	 * @param iLabelType
	 *            标签类型 0:普通标签(16位数字) 1:出版社标签(20位数字)
	 * @param iConsArea
	 *            消费地区
	 * @param iConsCheckCode
	 *            消费码
	 * @throws IOException
	 */
	private void sendProt_ConsInfo(DataOutputStream dos, short iTaskCode,
			long iLabel, short iLabelType, int iConsArea, short iConsCheckCode,
			short iTerminalType) throws IOException {
		short bodySize = countBodySize(iLabel, iLabelType, iConsArea,
				iConsCheckCode, iTerminalType);
		sendHeader(dos, iTaskCode, bodySize);
		sendiLabel(dos, iLabel);
		dos.writeShort(iLabelType);
		sendiAreaCode(dos, iConsArea);
		dos.writeShort(iConsCheckCode);
		dos.writeShort(iTerminalType);
		sendCheckCode(dos);
	}

	/**
	 * 1303和1304 <br/>
	 * 2015-4-10下午4:26:40
	 * 
	 * @param dis
	 * @param dos
	 * @param iTaskCode
	 *            任务号
	 * @param iLabel
	 *            标签Id
	 * @param iLbsAreaCode
	 *            消费地区,本地定位
	 * @param iConsCheckCode
	 *            消费验证码
	 * @throws IOException
	 */
	private void recProt_ConsInfo(DataInputStream dis, DataOutputStream dos,
			short iTaskCode, long iLabel, int iLbsAreaCode, short iConsCheckCode)
			throws IOException {
		// 选择标签类型，16位和20，目前只有16位的标签
		short iLabelType = 0;
		if (String.valueOf(iLabel).length() == 16) {
			iLabelType = 0;
		} else if (String.valueOf(iLabel).length() == 20) {
			iLabelType = 1;
		}
		sendProt_ConsInfo(dos, iTaskCode, iLabel, iLabelType, iLbsAreaCode,
				iConsCheckCode, imTerminalType);
		recHeader(dis);

		if (isTaskCode(iTaskCode)) {
			iFirstQueryTime = dis.readLong();
			iConsCount = dis.readInt();
			iFirstConsAreaCode = reciAreadCode(dis);
			iFirstConsTime = dis.readLong();
			recCheckCode(dis);
			debugLog(iTaskCode, toString());
			setSuccess(true);
		} else {
			recFFFF(dis, iTaskCode);
		}
	}

	/**
	 * 是否第一次 <br/>
	 * 2015-4-27下午5:14:23
	 * 
	 * @return true第一次，false非第一次
	 */
	public boolean isFirst() {
		return iConsCount <= 1;
	}

	/**
	 * 消费次数<br/>
	 * 当第一次的时候，消费次数为1。
	 * 
	 * @return
	 */
	public int getiConsCount() {
		return iConsCount;
	}

	/**
	 * 首次查询时间
	 */
	public long getiFirstQueryTime() {
		return iFirstQueryTime;
	}

	/**
	 * 首次查询时间，显示格式 2014年7月2日 11:49:46
	 */
	public String getFirstQueryTime() {
		return formatDate(iFirstQueryTime);
	}

	/**
	 * 消费:第一次消费地址Code
	 */
	public int getiFirstConsAreaCode() {
		return iFirstConsAreaCode;
	}

	/**
	 * 消费:第一次消费地址Name
	 */
	public String getFirstConsAreaName() {
		return AddressUtil.searchCityNameByNum(iFirstConsAreaCode);
	}

	/**
	 * 消费:第一次消费时间
	 */
	public long getiFirstConsTime() {
		return iFirstConsTime;
	}

	/**
	 * 消费:第一次消费时间,显示格式 2014年7月2日 11:49:46
	 */
	public String getFirstConsTime() {
		return formatDate(iFirstConsTime);
	}

	/**
	 * 2014年7月2日 11:49:46 <br/>
	 * yyyyMMddHHmmss===>yyyy-MM-dd HH:mm:ss
	 * 
	 * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
	 */
	private String formatDate(long date) {
		String retStr = "";
		if (date <= 0) {
			return retStr;
		}
		SimpleDateFormat sf1 = new SimpleDateFormat("yyyyMMddHHmmss");

		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		try {
			retStr = formatter.format(sf1.parse(String.valueOf(date)));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return retStr;

	}

	@Override
	public String toString() {
		return "Prot13 [imTerminalType=" + imTerminalType
				+ ", iFirstQueryTime=" + iFirstQueryTime + ", iConsCount="
				+ iConsCount + ", iFirstConsArea=" + iFirstConsAreaCode
				+ ", iFirstConsTime=" + iFirstConsTime + "]";
	}

	/********************************* 2015年4月13日 以下方法过时了 *************************************/

	/**
	 * 13普通模式,需要输入消费码<br/>
	 * 数据库记录消费次数<br/>
	 * 2014-11-12上午10:35:43 <br/>
	 * 废弃时间: 2015年4月13日<br/>
	 * 由替代: dealConsCount1303<br/>
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iLabelId
	 * @param iConsCheckCode
	 *            消费码，必须输入正确,传入0则报错
	 * @throws IOException
	 */
	@Deprecated
	private void dealConsCount13(DataInputStream dis, DataOutputStream dos,
			long iLabelId, short iConsCheckCode) throws IOException {
		if (iConsCheckCode <= 0) {
			errLog(iTaskCode13, "consCode is <=0 " + iConsCheckCode);
			return;
		}
		short taskCode = iTaskCode13;
		recProt(dis, taskCode, dos, iLabelId, iConsCheckCode);
	}

	/**
	 * 13.查询次数<br/>
	 * 数据库将不进行修改<br/>
	 * 2015-1-15下午3:49:53 
	 * 废弃时间: 2015年4月13日<br/>
	 * 由替代: dealQueryCount1303<br/>
	 * 
	 * @param dis
	 * @param dos
	 * @param iLabelId
	 * @throws IOException
	 */
	@Deprecated
	private void dealQueryConut13(DataInputStream dis, DataOutputStream dos,
			long iLabelId) throws IOException {
		short taskCode = iTaskCode13;
		short iConsCheckCode = 0;// 消费码设置为0
		recProt(dis, taskCode, dos, iLabelId, iConsCheckCode);
	}

	/**
	 * 1301汽配模式
	 * <p>
	 * 2014-11-12上午10:36:07
	 * </p>
	 * 废弃时间: 2015年4月13日<br/>
	 * 由替代: dealConsCount1304<br/>
	 * 
	 * @param socket
	 * @param dis
	 * @param dos
	 * @param iLabelId
	 * @param iConsCheckCode
	 * @throws IOException
	 */
	@Deprecated
	private void dealConsCount1301(DataInputStream dis, DataOutputStream dos,
			long iLabelId, short iConsCheckCode) throws IOException {
		short taskCode = iTaskCode1301;
		recProt(dis, taskCode, dos, iLabelId, iConsCheckCode);
	}

	/**
	 * 13. 创建时间：2014-6-25下午5:21:44<br/>
	 * 修改时间：2014-11-12 10:17:35 增加1301号，云南汽配模式<br/>
	 * 
	 * @param dos
	 * @param iLabel
	 *            标签Id
	 * @param iLabelType
	 *            标签类型 0:普通标签(16位数字) 1:出版社标签(20位数字)
	 * @param iConsCheckCode
	 *            消费验证码
	 * @param iTerminalType
	 *            终端系统类型 1000：IOS终端 <br/>
	 *            2000：Android终端 <br/>
	 *            3000：Web终端<br/>
	 *            4000：电话
	 * @throws IOException
	 */
	private void sendProt(DataOutputStream dos, short iTaskCode, long iLabel,
			short iLabelType, short iConsCheckCode, short iTerminalType)
			throws IOException {

		short bodySize = countBodySize(iLabel, iLabelType, iConsCheckCode,
				iTerminalType);
		sendHeader(dos, iTaskCode, bodySize);
		sendiLabel(dos, iLabel);
		dos.writeShort(iLabelType);
		dos.writeShort(iConsCheckCode);
		dos.writeShort(iTerminalType);
		sendCheckCode(dos);
	}

	/**
	 * 13.消费信息查询(语音) 2014-6-25下午5:21:44
	 * 
	 * @param dos
	 * @param iLabelId
	 *            标签Id
	 * @param iLabelType
	 *            标签类型 0:普通标签(16位数字) 1:出版社标签(20位数字)
	 * @param iConsCheckCode
	 *            消费验证码
	 * @throws IOException
	 */
	private void recProt(DataInputStream dis, short iTaskCode,
			DataOutputStream dos, long iLabelId, short iConsCheckCode)
			throws IOException {
		// 选择标签类型，16位和20，目前只有16位的标签
		short iLabelType = 0;
		if (String.valueOf(iLabelId).length() == 16) {
			iLabelType = 0;
		} else if (String.valueOf(iLabelId).length() == 20) {
			iLabelType = 1;
		}
		sendProt(dos, iTaskCode, iLabelId, iLabelType, iConsCheckCode,
				(short) 2000);
		recHeader(dis);

		if (isTaskCode(iTaskCode)) {
			long iFirstQueryTime = dis.readLong();
			int iConsCount = dis.readInt();
			recCheckCode(dis);
			debugLog(iTaskCode, "iFirstQueryTime:" + iFirstQueryTime
					+ ";iQueryCount" + iConsCount);
			this.iConsCount = iConsCount;
		} else {
			recFFFF(dis, iTaskCode);
		}
	}

	/**
	 * 被1305替换<br/>
	 * 1302 稽查查看消费次数<br/>
	 * 数据库不增加次数<br/>
	 * 调用方法：getiConsCount()获取消费查询次数<br/>
	 * 2015-3-5下午3:15:53<br/>
	 * 
	 * @param dis
	 * @param dos
	 * @param iLabelId
	 *            追溯码
	 * @throws IOException
	 */
	@Deprecated
	private void dealCheckConsCount1302(DataInputStream dis,
			DataOutputStream dos, long iLabelId) throws IOException {
		short taskCode = iTaskCode1302;
		short iConsCheckCode = 0;
		recProt(dis, taskCode, dos, iLabelId, iConsCheckCode);
	}

}
