package com.jsowell.thirdparty.ningxiajiaotou.service.impl;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.ThirdPartyPlatformConfig;
import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryOrdersInfoDTO;
import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryStationInfoDTO;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.ConnectorInfoVO;
import com.jsowell.pile.vo.ningxiajiaotou.NXJTOrderVO;
import com.jsowell.pile.vo.ningxiajiaotou.NXJTStationInfoVO;
import com.jsowell.pile.vo.uniapp.customer.OrderVO;
import com.jsowell.pile.thirdparty.CommonParamsDTO;
import com.jsowell.thirdparty.lianlian.service.LianLianService;
import com.jsowell.thirdparty.platform.util.Cryptos;
import com.jsowell.thirdparty.platform.util.Encodes;
import com.jsowell.thirdparty.platform.util.GBSignUtils;
import com.jsowell.thirdparty.ningxiajiaotou.service.NXJTService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 宁夏交投Service
 *
 * @author Lemon
 * @Date 2023/11/13 8:58:06
 */
@Service
public class NXJTServiceImpl implements NXJTService {

    @Autowired
    private LianLianService lianLianService;

    @Autowired
    private PileStationInfoService pileStationInfoService;

    @Autowired
    private ThirdPartyPlatformConfigService thirdPartyPlatformConfigService;

    @Autowired
    private PileBasicInfoService pileBasicInfoService;

    @Autowired
    private PileConnectorInfoService pileConnectorInfoService;

    @Autowired
    private OrderBasicInfoService orderBasicInfoService;

    /**
     * 生成令牌
     * @param dto
     * @return
     * @throws UnsupportedEncodingException
     */
    @Override
    public Map<String, String> generateToken(CommonParamsDTO dto) throws UnsupportedEncodingException {
        return lianLianService.generateToken(dto);
    }

    /**
     * 获取令牌
     * @param urlAddress
     * @param operatorId
     * @param operatorSecret
     * @param dataSecretIv
     * @param signSecret
     * @param dataSecret
     * @return
     */
    @Override
    public String getToken(String urlAddress, String operatorId, String operatorSecret, String dataSecretIv, String signSecret, String dataSecret) {
        return lianLianService.getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret);
    }

    /**
     * 查询站点信息
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> queryStationsInfo(NXJTQueryStationInfoDTO dto) {
        int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();

        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        // 分页
        PageUtils.startPage(pageNo, pageSize);
        List<NXJTStationInfoVO> stationInfos = pileStationInfoService.NXJTQueryStationsInfo(dto);
        PageInfo<NXJTStationInfoVO> pageInfo = new PageInfo<>(stationInfos);

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("pageNo", pageInfo.getPageNum());
        map.put("pageCount", pageInfo.getPages());
        map.put("itemSize", pageInfo.getList().size());
        map.put("stationInfos", pageInfo.getList());

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(map).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }

    /**
     * 查询充电站中空闲桩数量
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> queryFreePileNumber(NXJTQueryStationInfoDTO dto) {
        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        long stationId = Long.parseLong(dto.getStationId());
        List<ConnectorInfoVO> connectorList = pileConnectorInfoService.getUniAppConnectorList(stationId);
        // 先根据pileSn分组，获取设备总数
        List<String> pileSnList = connectorList.stream()
                .map(ConnectorInfoVO::getPileSn)
                .collect(Collectors.toList());
        // 根据枪口编号批量查询枪口状态
        Map<String, Integer> pileTypeNum = pileConnectorInfoService.getPileTypeNum(stationId);
        // Integer fastTotal = pileTypeNum.get("fastTotal");// 快充总数
        Integer fastFree = pileTypeNum.get("fastFree"); // 快充空闲
        // Integer slowTotal = pileTypeNum.get("slowTotal");// 慢充总数
        Integer slowFree = pileTypeNum.get("slowFree");// 慢充空闲

        int freePileNumber = fastFree + slowFree; // 总空闲数量 = 快充空闲 + 慢充空闲
        int pileNumber = pileSnList.size(); // 总设备数 就是桩号集合的长度

        // 拼装参数
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("pileNum", pileNumber);
        map.put("freePileNum", freePileNumber);

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(map).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }

    /**
     * 查询订单信息
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> queryOrdersInfoByPlateNumber(NXJTQueryOrdersInfoDTO dto) {
        List<NXJTOrderVO> resultList = new ArrayList<>();
        int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();

        ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
        if (configInfo == null) {
            return null;
        }
        // 如果开始时间、结束时间为空，则默认为一个月内
        if (StringUtils.isBlank(dto.getStartTime()) && StringUtils.isBlank(dto.getEndTime())) {
            dto.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addMonths(new Date(), -1)));
            dto.setEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()));
        }
        // 分页
        PageUtils.startPage(pageNo, pageSize);
        // 根据车牌号查询消费情况
        List<OrderVO> orderVOList = orderBasicInfoService.getOrderInfoByNXJT(dto);
        PageInfo<OrderVO> pageInfo = new PageInfo<>(orderVOList);
        List<OrderVO> list = pageInfo.getList();
        NXJTOrderVO vo;
        for (OrderVO orderVO : list) {
            // 拼装成对接平台所需格式
            vo = new NXJTOrderVO();
            vo.setLicensePlateNumber(orderVO.getLicensePlateNumber());
            vo.setOrderAmount(orderVO.getOrderAmount());
            vo.setChargeTime(orderVO.getStartTime());
            vo.setStationName(orderVO.getStationName());
            vo.setLicensePlateNumberColor(1);

            resultList.add(vo);
        }
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("pageNo", pageInfo.getPageNum());
        map.put("pageCount", pageInfo.getPages());
        map.put("itemSize", resultList.size());
        map.put("orderInfos", resultList);

        // 加密
        Map<String, String> resultMap = Maps.newLinkedHashMap();
        // 加密数据
        byte[] encryptText = Cryptos.aesEncrypt(JSON.toJSONString(map).getBytes(),
                configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
        String encryptData = Encodes.encodeBase64(encryptText);

        resultMap.put("Data", encryptData);
        // 生成sig
        String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
        resultMap.put("Sig", resultSign);

        return resultMap;
    }

    /**
     * 查询指定时间内的订单信息
     * @param dto
     * @return
     */
    @Override
    public Map<String, String> queryOrdersInfo(NXJTQueryOrdersInfoDTO dto) {
        // 由于调用的查询方法、拼装的参数均相同，因此直接调用上面方法
        // 两个方法仅入参不同
        return queryOrdersInfoByPlateNumber(dto);
        // return null;
    }
}
