package com.jsowell.common.core.domain.ykc;

import com.jsowell.common.util.BytesUtil;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.YKCUtils;

/**
 * 云快充 帧类型码
 * FrameTypeCode
 * frame
 */
public enum YKCFrameTypeCode {

	LOGIN_CODE(0x01, "充电桩登录认证"),
	LOGIN_ANSWER_CODE(0x02, "登录认证应答"),

	HEART_BEAT_CODE(0x03, "充电桩心跳包"),
	HEART_BEAT_ANSWER_CODE(0x04, "心跳包应答"),

	BILLING_TEMPLATE_VALIDATE_CODE(0x05, "计费模型验证请求"),
	BILLING_TEMPLATE_VALIDATE_ANSWER_CODE(0x06, "计费模型验证请求应答"),

	BILLING_TEMPLATE_CODE(0x09, "充电桩计费模型请求"),
	BILLING_TEMPLATE_ANSWER_CODE(0x0A, "计费模型请求应答"),

	UPLOAD_REAL_TIME_MONITOR_DATA_OLD_VERSION_CODE(0x11, "上传实时监测数据V1.3"),
	READ_REAL_TIME_MONITOR_DATA_CODE(0x12, "读取实时监测数据"),
	UPLOAD_REAL_TIME_MONITOR_DATA_CODE(0x13, "上传实时监测数据"),

	CHARGING_HANDSHAKE_CODE(0x15, "充电握手"),
	PARAMETER_CONFIGURATION_CODE(0x17, "参数配置"),
	CHARGE_END_CODE(0X19, "充电结束"),
	ERROR_MESSAGE_CODE(0x1B, "错误报文"),
	BMS_ABORT_DURING_CHARGING_PHASE_CODE(0x1D, "充电阶段BMS中止"),
	THE_CHARGER_IS_ABORTED_DURING_THE_CHARGING_PHASE_CODE(0X21, "充电阶段充电机中止"),
	CHARGING_PROCESS_BMS_DEMAND_AND_CHARGER_OUTPUT_CODE(0X23, "充电过程 BMS 需求与充电机输出"),
	CHARGING_PROCESS_BMS_INFORMATION_CODE(0X25, "充电过程 BMS 信息"),

	REQUEST_START_CHARGING_CODE(0x31, "充电桩主动申请启动充电"),
	CONFIRM_START_CHARGING_CODE(0x32, "运营平台确认启动充电"),

	REMOTE_START_CHARGING_ANSWER_CODE(0x33, "远程启动充电命令回复"),
	REMOTE_CONTROL_START_CODE(0x34, "运营平台远程控制启机"),

	REMOTE_STOP_CHARGING_ANSWER_CODE(0x35, "远程停机命令回复"),
	REMOTE_STOP_CHARGING_CODE(0x36, "运营平台远程停机"),


	TRANSACTION_RECORDS_CODE(0x3B, "交易记录"),
	TRANSACTION_RECORDS_OLD_VERSION_CODE(0x39, "交易记录V1.3"),
	TRANSACTION_RECORDS_CONFIRM_CODE(0x40, "交易记录确认"),

	REMOTE_ACCOUNT_BALANCE_UPDATE_CODE(0x42, "远程账户余额更新"),
	REMOTE_ACCOUNT_BALANCE_UPDATE_ANSWER_CODE(0x41, "余额更新应答"),

	OFFLINE_CARD_DATA_SYNCHRONIZATION_CODE(0x44, "离线卡数据同步"),
	OFFLINE_CARD_DATA_SYNCHRONIZATION_ANSWER_CODE(0x43, "离线卡数据同步应答"),

	OFFLINE_CARD_DATA_CLEANING_CODE(0x46, "离线卡数据清除"),
	OFFLINE_CARD_DATA_CLEANING_ANSWER_CODE(0x45, "离线卡数据清除应答"),

	OFFLINE_CARD_DATA_QUERY_CODE(0x48, "离线卡数据查询"),
	OFFLINE_CARD_DATA_QUERY_ANSWER_CODE(0x47, "离线卡数据查询应答"),

	CHARGING_PILE_WORKING_PARAMETER_SETTING_CODE(0x52, "充电桩工作参数设置"),
	CHARGING_PILE_WORKING_PARAMETER_SETTING_ANSWER_CODE(0x51, "充电桩工作参数设置应答"),

	TIME_CHECK_SETTING_CODE(0x56, "对时设置"),
	TIME_CHECK_SETTING_ANSWER_CODE(0x55, "对时设置应答"),

	BILLING_TEMPLATE_SETTING_CODE(0x58, "计费模型设置"),
	BILLING_TEMPLATE_SETTING_ANSWER_CODE(0x57, "计费模型设置应答"),

	GROUND_LOCK_DATA_UPLOAD_CODE(0x61, "地锁数据上送"),
	REMOTE_CONTROL_GROUND_LOCK_LIFTING_CODE(0x62, "遥控地锁升降"),
	CHARGING_PILE_RESPOND_GROUND_LOCK_LIFTING_CODE(0X63, "充电桩响应地锁升降数据"),

	REMOTE_RESTART_CODE(0x92, "远程重启"),
	REMOTE_RESTART_ANSWER_CODE(0x91, "远程重启应答"),

	REMOTE_UPDATE_CODE(0x94, "远程更新"),
	REMOTE_UPDATE_ANSWER_CODE(0x93, "远程更新应答"),

	REMOTE_ISSUE_QRCODE_CODE(0xF0, "后台远程下发二维码前缀指令"),
	REMOTE_ISSUE_QRCODE_ANSWER_CODE(0xF1, "桩应答远程下发二维码前缀指令"),

	/**
	 * 补充内容
	 */
	QUERY_PILE_WORK_PARAMS_CODE(0X26, "平台査询工作参数"),
	QUERY_PILE_WORK_PARAMS_ANSWER_CODE(0X27, "充电桩査询工作参数回复"),

	SETTING_PILE_WORK_PARAMS_CODE(0x28, " 平台设置工作参数"),
	SETTING_PILE_WORK_PARAMS_ANSWER_CODE(0x29, "平台设置工作参数回复"),

	// 自定义FrameType
	PILE_LOG_OUT(9999, "充电桩退出"),


	;

	YKCFrameTypeCode(int code, String value) {
		this.code = code;
		this.value = value;
	}

	private int code;
	private String value;

	public int getCode() {
		return code;
	}

	public String getValue() {
		return value;
	}

	public byte[] getBytes() {
		return BytesUtil.intToBytesLittle(code, 1);
	}

	public static void main(String[] args) {
		byte[] bytes = BytesUtil.intToBytesLittle(9999, 1);
		System.out.println(YKCUtils.frameType2Str(bytes));
	}

	public static YKCFrameTypeCode fromCode(byte code) {
		for (YKCFrameTypeCode item : YKCFrameTypeCode.values()) {
			if (item.getCode() == code) {
				return item;
			}
		}
		return null;
	}

	public static String getFrameTypeStr(String frameType) {
		for (YKCFrameTypeCode item : YKCFrameTypeCode.values()) {
			String str = YKCUtils.frameType2Str(item.getBytes());
			if (StringUtils.equals(frameType, str)) {
				return item.getValue();
			}
		}
		return "";
	}

	/**
	 * 请求应答 帧类型关系
	 */
	public enum ResponseRelation {
		// 登录
		LOGIN(LOGIN_CODE.getCode(), LOGIN_ANSWER_CODE.getCode()),
		// 心跳
		HEART_BEAT(HEART_BEAT_CODE.getCode(), HEART_BEAT_ANSWER_CODE.getCode()),
		// 计费模板验证
		BILLING_TEMPLATE_VALIDATE(BILLING_TEMPLATE_VALIDATE_CODE.getCode(), BILLING_TEMPLATE_VALIDATE_ANSWER_CODE.getCode()),
		// 计费模板请求
		BILLING_TEMPLATE(BILLING_TEMPLATE_CODE.getCode(), BILLING_TEMPLATE_ANSWER_CODE.getCode()),
		// 请求开始充电
		START_CHARGING(REQUEST_START_CHARGING_CODE.getCode(), CONFIRM_START_CHARGING_CODE.getCode()),
		// 远程请求充电
		REMOTE_START_CHARGING(REMOTE_CONTROL_START_CODE.getCode(), REMOTE_START_CHARGING_ANSWER_CODE.getCode()),
		// 远程停止充电
		REMOTE_STOP_CHARGING(REMOTE_STOP_CHARGING_CODE.getCode(), REMOTE_STOP_CHARGING_ANSWER_CODE.getCode()),
		// 交易记录
		TRANSACTION_RECORDS(TRANSACTION_RECORDS_CODE.getCode(), TRANSACTION_RECORDS_CONFIRM_CODE.getCode()),
		// 远程账户更新
		REMOTE_ACCOUNT_BALANCE_UPDATE(REMOTE_ACCOUNT_BALANCE_UPDATE_CODE.getCode(), REMOTE_ACCOUNT_BALANCE_UPDATE_ANSWER_CODE.getCode());

		// 请求帧类型
		private int requestFrameType;

		// 响应帧类型
		private int responseFrameType;

		public int getRequestFrameType() {
			return requestFrameType;
		}

		public void setRequestFrameType(int requestFrameType) {
			this.requestFrameType = requestFrameType;
		}

		public int getResponseFrameType() {
			return responseFrameType;
		}

		public void setResponseFrameType(int responseFrameType) {
			this.responseFrameType = responseFrameType;
		}

		ResponseRelation(int requestFrameType, int responseFrameType) {
			this.requestFrameType = requestFrameType;
			this.responseFrameType = responseFrameType;
		}

		// 根据请求帧类型 获取应答帧类型
		public static int getResponseFrameType(int requestFrameType) {
			for (ResponseRelation responseRelation : ResponseRelation.values()) {
				if (responseRelation.getRequestFrameType() == requestFrameType) {
					return responseRelation.getResponseFrameType();
				}
			}
			return 0;
		}

		public static byte[] getResponseFrameType(byte[] requestFrameType) {
			int frameType = BytesUtil.bytesToInt(requestFrameType);
			return BytesUtil.intToBytes(getResponseFrameType(frameType), 1);
		}
	}

}
