package com.hfkj.service.gas.impl;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.config.MqttProviderConfig;
import com.hfkj.device.sanmisen.PrinterTemplate;
import com.hfkj.device.spyun.SpPrinterConfig;
import com.hfkj.device.spyun.SpPrinterTemplate;
import com.hfkj.dao.BsGasClassGroupTaskMapper;
import com.hfkj.entity.*;
import com.hfkj.model.GasClassGroupTaskDataCount;
import com.hfkj.model.GasClassGroupTaskOilCount;
import com.hfkj.service.BsDeviceService;
import com.hfkj.service.merchant.BsMerchantService;
import com.hfkj.service.gas.BsGasClassGroupService;
import com.hfkj.service.gas.BsGasClassGroupTaskService;
import com.hfkj.sysenum.DeviceTypeEnum;
import com.hfkj.sysenum.gas.GasClassGroupTaskStatus;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service("gasClassGroupTask")
public class BsGasClassGroupTaskServiceImpl implements BsGasClassGroupTaskService {

    @Resource
    private BsGasClassGroupTaskMapper gasClassGroupTaskMapper;

    @Resource
    private BsGasClassGroupService gasClassGroupService;

    @Resource
    private BsMerchantService merchantService;

    @Resource
    private BsDeviceService deviceService;
    @Resource
    private MqttProviderConfig mqttProviderConfig;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void startGroupTask(Long gasId, Long gasClassGroupId) {
        // 查询加油站
        BsMerchant merchant = merchantService.getMerchant(gasId);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到加油站信息");
        }

        // 查询进行中的任务
        Map<String, Object> param = new HashMap<>();
        param.put("merId", merchant.getId());
        param.put("status", GasClassGroupTaskStatus.status1.getStatus());
        List<BsGasClassGroupTask> list = getGroupTaskList(param);
        if (!list.isEmpty()) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已有班组正在进行中，请结束班组或交换班组");
        }
        // 查询班组信息
        BsGasClassGroup group = gasClassGroupService.getDetailById(gasClassGroupId);
        if (group == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到班组信息");
        }

        BsGasClassGroupTask groupTask = new BsGasClassGroupTask();
        groupTask.setGasClassGroupId(group.getId());
        groupTask.setGasClassGroupName(group.getName());
        groupTask.setMerId(merchant.getId());
        groupTask.setMerName(merchant.getMerName());
        groupTask.setStartTime(new Date());
        groupTask.setClassNum(gasClassGroupTaskMapper.getLatestClassNum(merchant.getId()) + 1);
        editGroupTask(groupTask);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void endGroupTask(Long gasId) {
        // 查询进行中的任务
        Map<String, Object> param = new HashMap<>();
        param.put("merId", gasId);
        param.put("status", GasClassGroupTaskStatus.status1.getStatus());
        List<BsGasClassGroupTask> list = getGroupTaskList(param);
        if (!list.isEmpty()) {
            BsGasClassGroupTask groupTask = list.get(0);
            groupTask.setEndTime(new Date());
            groupTask.setStatus(GasClassGroupTaskStatus.status2.getStatus());
            // 统计
            GasClassGroupTaskDataCount dataCount = countGroupTaskData(gasId, groupTask.getClassNum(), groupTask.getId(), groupTask.getStatus(), groupTask.getStartTime(), groupTask.getEndTime());
            groupTask.setDataCount(JSONObject.toJSONString(dataCount));
            editGroupTask(groupTask);

            // 查询加油站打印机
            List<BsDevice> deviceList = deviceService.getDeviceByMer(gasId);
            for (BsDevice device : deviceList) {
                if (device.getType().equals(DeviceTypeEnum.type1.getType())) {
                    new Thread(() -> {
                        try {
                            // 推送打印机
                            SpPrinterConfig spPrinterConfig = new SpPrinterConfig();
                            spPrinterConfig.print(device.getDeviceSn(), SpPrinterTemplate.classGroupCountTemp(dataCount, false), 1);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }).start();
                } else if (device.getType().equals(DeviceTypeEnum.type2.getType())) {
                    new Thread(() -> {
                        try {
                            JSONObject publishParam = new JSONObject();
                            publishParam.put("id", System.currentTimeMillis());
                            publishParam.put("type", 5);
                            publishParam.put("vType", 0);
                            publishParam.put("vMessage", "班结数据汇总，请注意查收");
                            publishParam.put("contents", PrinterTemplate.classGroupCountTemp(dataCount ,false));
                            mqttProviderConfig.publish(1, false, device.getDeviceSn()+"/submsg", publishParam.toJSONString());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }).start();
                }
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void swapGroupTask(Long gasId, Long gasClassGroupId) {
        // 任务结束
        endGroupTask(gasId);

        // 开启新的任务
        startGroupTask(gasId, gasClassGroupId);
    }

    @Override
    public GasClassGroupTaskDataCount countGroupTaskData(Long gasId, Integer classNum, Long groupTaskId, Integer status, Date startTime, Date endTime) {
        GasClassGroupTaskDataCount dataCount = new GasClassGroupTaskDataCount();
        dataCount.setClassNum(classNum);
        dataCount.setStatus(status);
        dataCount.setStartTime(startTime);
        dataCount.setEndTime(endTime);

        // 加油汇总
        Map<String, Object> refuelData = gasClassGroupTaskMapper.countRefuelData(groupTaskId);
        dataCount.setRefuelPrice(new BigDecimal(MapUtils.getString(refuelData, "refuelPrice")));
        dataCount.setRefuelNum(MapUtils.getInteger(refuelData, "refuelNum"));
        dataCount.setRefuelLiters(new BigDecimal(MapUtils.getString(refuelData, "refuelLiters")));

        // 退款汇总
        Map<String, Object> refundData = gasClassGroupTaskMapper.countRefundData(groupTaskId);
        dataCount.setRefundPrice(new BigDecimal(MapUtils.getString(refundData, "refundPrice")));
        dataCount.setRefundNum(MapUtils.getInteger(refundData, "refundNum"));
        dataCount.setRefundLiters(new BigDecimal(MapUtils.getString(refundData, "refundLiters")));


        // 油品汇总
        List<Map<String, Object>> oilDataList = gasClassGroupTaskMapper.countOilData(gasId, groupTaskId);

        List<GasClassGroupTaskOilCount> oilCountList = new ArrayList<>();
        for (Map<String, Object> oilData : oilDataList) {
            GasClassGroupTaskOilCount oilCount = new GasClassGroupTaskOilCount();
            oilCount.setOilNo(MapUtils.getInteger(oilData, "oilNo"));
            oilCount.setRefuelPrice(new BigDecimal(MapUtils.getString(oilData, "refuelPrice")));
            oilCount.setRefuelNum(MapUtils.getInteger(oilData, "refuelNum"));
            oilCount.setRefuelLiters(new BigDecimal(MapUtils.getString(oilData, "refuelLiters")));
            oilCountList.add(oilCount);
        }
        dataCount.setGroupTaskOilCountList(oilCountList);

        return dataCount;
    }

    @Override
    public void editGroupTask(BsGasClassGroupTask gasClassGroupTask) {
        if (gasClassGroupTask.getId() == null) {
            gasClassGroupTask.setStatus(GasClassGroupTaskStatus.status1.getStatus());
            gasClassGroupTask.setCreateTime(new Date());
            gasClassGroupTask.setUpdateTime(new Date());
            gasClassGroupTaskMapper.insert(gasClassGroupTask);
        } else {
            gasClassGroupTask.setUpdateTime(new Date());
            gasClassGroupTaskMapper.updateByPrimaryKey(gasClassGroupTask);
        }
    }

    @Override
    public BsGasClassGroupTask getDetailById(Long groupTaskId) {
        return gasClassGroupTaskMapper.selectByPrimaryKey(groupTaskId);
    }

    @Override
    public List<BsGasClassGroupTask> getGroupTaskList(Map<String, Object> param) {
        BsGasClassGroupTaskExample example = new BsGasClassGroupTaskExample();
        BsGasClassGroupTaskExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(GasClassGroupTaskStatus.status0.getStatus());

        if (MapUtils.getLong(param, "gasClassGroupId") != null) {
            criteria.andGasClassGroupIdEqualTo(MapUtils.getLong(param, "gasClassGroupId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "gasClassGroupName"))) {
            criteria.andGasClassGroupNameLike("%" + MapUtils.getString(param, "gasClassGroupName") + "%");
        }

        if (MapUtils.getLong(param, "merId") != null) {
            criteria.andMerIdEqualTo(MapUtils.getLong(param, "merId"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "gasClassGroupName"))) {
            criteria.andGasClassGroupNameLike("%" + MapUtils.getString(param, "gasClassGroupName") + "%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        example.setOrderByClause("create_time desc");
        return gasClassGroupTaskMapper.selectByExample(example);
    }

    @Override
    public BsGasClassGroupTask getCurrentTaskByMerId(Long merId) {
        BsGasClassGroupTaskExample example = new BsGasClassGroupTaskExample();
        example.createCriteria()
                .andMerIdEqualTo(merId)
                .andStatusEqualTo(GasClassGroupTaskStatus.status1.getStatus());
        List<BsGasClassGroupTask> list = gasClassGroupTaskMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }
}
