package com.jsowell.service;

import com.google.common.collect.Lists;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.ykcCommond.GetRealTimeMonitorDataCommand;
import com.jsowell.pile.domain.ykcCommond.IssueQRCodeCommand;
import com.jsowell.pile.domain.ykcCommond.ProofreadTimeCommand;
import com.jsowell.pile.domain.ykcCommond.PublishPileBillingTemplateCommand;
import com.jsowell.pile.domain.ykcCommond.RebootCommand;
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
import com.jsowell.pile.domain.ykcCommond.UpdateFirmwareCommand;
import com.jsowell.pile.service.YKCPushCommandService;
import com.jsowell.pile.domain.PileBillingRelation;
import com.jsowell.pile.domain.PileBillingTemplate;
import com.jsowell.pile.dto.PublishBillingTemplateDTO;
import com.jsowell.pile.service.IPileBasicInfoService;
import com.jsowell.pile.service.IPileBillingTemplateService;
import com.jsowell.pile.service.IPileStationInfoService;
import com.jsowell.pile.vo.web.BillingTemplateVO;
import com.jsowell.pile.vo.web.PileDetailVO;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class PileRemoteService {
	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private IPileBillingTemplateService pileBillingTemplateService;

	@Autowired
	private IPileBasicInfoService pileBasicInfoService;

	@Autowired
	private YKCPushCommandService ykcPushCommandService;

	@Autowired
	private IPileStationInfoService pileStationInfoService;

	/**
	 * 获取充电桩实时数据信息
	 *
	 * @param pileSn        充电桩sn
	 * @param connectorCode 枪口号
	 */
	public void getRealTimeMonitorData(String pileSn, String connectorCode) {
		if (StringUtils.isNotEmpty(pileSn) || StringUtils.isNotEmpty(connectorCode)) {
			GetRealTimeMonitorDataCommand command = GetRealTimeMonitorDataCommand.builder()
					.pileSn(pileSn)
					.connectorCode(connectorCode)
					.build();
			ykcPushCommandService.pushGetRealTimeMonitorDataCommand(command);
		}

	}

	/**
	 * 重启指令
	 *
	 * @param pileSn 充电桩sn
	 */
	public void reboot(String pileSn) {
		RebootCommand command = RebootCommand.builder().pileSn(pileSn).build();
		ykcPushCommandService.pushRebootCommand(command);
	}

	/**
	 * 远程启动充电  0x34
	 *
	 * @param pileSn 充电桩sn
	 */
	public void remoteStartCharging(String pileSn, String connectorCode, String transactionCode, BigDecimal accountBalance) {
		// String s = "550314127823050120180619144446808800000000000101000000100000057300000000D14B0A54A0860100";
		if (StringUtils.isEmpty(pileSn) || StringUtils.isEmpty(connectorCode)) {
			log.warn("远程启动充电, 充电桩编号和枪口号不能为空");
			return;
		}
		log.info("=====平台下发指令=====: 远程启动充电, 桩号：{}, 枪口号：{}", pileSn, connectorCode);
		StartChargingCommand startChargingCommand = StartChargingCommand.builder()
				.pileSn(pileSn)
				.connectorCode(connectorCode)
				.transactionCode(transactionCode)
				.chargeAmount(accountBalance)
				.build();
		ykcPushCommandService.pushStartChargingCommand(startChargingCommand);
	}

	/**
	 * 远程停止充电
	 */
	public void remoteStopCharging(String pileSn, String connectorCode) {
		StopChargingCommand command = StopChargingCommand.builder()
				.pileSn(pileSn)
				.connectorCode(connectorCode)
				.build();
		ykcPushCommandService.pushStopChargingCommand(command);
	}

	/**
	 * 下发充电桩二维码
	 *
	 * @param pileSn 充电桩sn
	 */
	public void issueQRCode(String pileSn) {
		issueQRCode(pileSn, null);
	}

	public void issueQRCode(String pileSn, String qrcodePrefix) {
		IssueQRCodeCommand command = IssueQRCodeCommand.builder().pileSn(pileSn).build();
		if (StringUtils.isNotBlank(qrcodePrefix)) {
			command.setQrcodePrefix(qrcodePrefix);
		}
		ykcPushCommandService.pushIssueQRCodeCommand(command);
	}

	/**
	 * 充电桩对时
	 *
	 * @param pileSn 充电桩sn
	 */
	public void proofreadTime(String pileSn) {

		ProofreadTimeCommand command = ProofreadTimeCommand.builder().pileSn(pileSn).build();
		ykcPushCommandService.pushProofreadTimeCommand(command);
	}

	/**
	 * 下发充电桩计费模型
	 */
	public void publishPileBillingTemplate(String pileSn, BillingTemplateVO billingTemplateVO) {

		PublishPileBillingTemplateCommand command = PublishPileBillingTemplateCommand.builder()
				.billingTemplateVO(billingTemplateVO)
				.pileSn(pileSn)
				.build();
		ykcPushCommandService.pushPublishPileBillingTemplate(command);
	}

	/**
	 * 下发计费模板
	 * @param dto
	 * @return
	 */
	public boolean publishBillingTemplate(PublishBillingTemplateDTO dto) {
		// 获取计费模板信息
		BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateByTemplateId(dto.getTemplateId());
		if (billingTemplateVO == null) {
			log.warn("获取计费模板信息, 通过模板id:{}查询计费模板为null", dto.getTemplateId());
			return false;
		}
		// 更新计费模板的发布时间
		PileBillingTemplate pileBillingTemplate = new PileBillingTemplate();
		pileBillingTemplate.setId(Long.valueOf(billingTemplateVO.getTemplateId()));
		pileBillingTemplate.setPublishTime(new Date());
		pileBillingTemplateService.updatePileBillingTemplate(pileBillingTemplate);

		// 获取到站点下所有的桩
		List<PileDetailVO> pileList = pileBasicInfoService.selectPileListByStationIds(Lists.newArrayList(Long.valueOf(dto.getStationId())));
		if (CollectionUtils.isEmpty(pileList)) {
			log.warn("获取到站点下所有的桩, 通过站点id:{}查询充电桩列表为空", dto.getStationId());
			return false;
		}

		// 保存计费模板和桩的关系
		List<PileBillingRelation> relationList = Lists.newArrayList();
		for (PileDetailVO pileInfoVO : pileList) {
			// push
			publishPileBillingTemplate(pileInfoVO.getPileSn(), billingTemplateVO);

			// 入库
			relationList.add(PileBillingRelation.builder()
					.pileSn(pileInfoVO.getPileSn())
					.billingTemplateCode(billingTemplateVO.getTemplateCode())
					.stationId(dto.getStationId())
					.build());
		}

		if (CollectionUtils.isNotEmpty(relationList)) {
			pileBillingTemplateService.insertPileBillingRelation(relationList);
		}
		return true;
	}

	/**
	 * 远程更新
	 *
	 * @param pileSns 前台传的桩号集合
	 */
	public void updateFirmware(List<String> pileSns) {
		//
		UpdateFirmwareCommand command = UpdateFirmwareCommand.builder().pileSnList(pileSns).build();
		ykcPushCommandService.pushUpdateFileCommand(command);
	}
}
