package com.hfkj.service.gas.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsGasOilPriceTaskMapper;
import com.hfkj.entity.BsGasOilPrice;
import com.hfkj.entity.BsGasOilPriceTask;
import com.hfkj.entity.BsGasOilPriceTaskExample;
import com.hfkj.mqtopic.TaskTopic;
import com.hfkj.msg.MsgTopic;
import com.hfkj.service.gas.BsGasOilPriceOfficialService;
import com.hfkj.service.gas.BsGasOilPriceService;
import com.hfkj.service.gas.BsGasOilPriceTaskService;
import com.hfkj.sysenum.gas.GasTaskExecutionTypeEnum;
import com.hfkj.sysenum.gas.GasTaskPriceTypeEnum;
import com.hfkj.sysenum.gas.GasTaskStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("gasOilPriceTaskService")
public class BsGasOilPriceTaskServiceImpl implements BsGasOilPriceTaskService {

    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private BsGasOilPriceTaskMapper gasOilPriceTaskMapper;
    @Resource
    private BsGasOilPriceService gasOilPriceService;
    @Resource
    private BsGasOilPriceOfficialService gasOilPriceOfficialService;

    @Override
    public void editData(BsGasOilPriceTask gasOilPriceTask) {
        if (gasOilPriceTask.getId() == null) {
            gasOilPriceTask.setStatus(GasTaskStatusEnum.status1.getStatus());
            gasOilPriceTask.setCreateTime(new Date());
            gasOilPriceTask.setUpdateTime(new Date());
            gasOilPriceTaskMapper.insert(gasOilPriceTask);
        } else {
            gasOilPriceTaskMapper.updateByPrimaryKey(gasOilPriceTask);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED)
    public void batchAddTask(List<BsGasOilPriceTask> taskList) {
        for (BsGasOilPriceTask task : taskList) {
            addTask(task);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED)
    public void addTask(BsGasOilPriceTask gasOilPriceTask) {
        editData(gasOilPriceTask);
        try {
            // 立刻执行
            if (gasOilPriceTask.getExecutionType().equals(GasTaskExecutionTypeEnum.type1.getStatus())) {
                businessHandle(gasOilPriceTask);

            } else if (gasOilPriceTask.getExecutionType().equals(GasTaskExecutionTypeEnum.type2.getStatus())) {
                long time = DateUtil.getSecondDiff(new Date(), gasOilPriceTask.getStartTime());
                if (time >= 1) {
                    Message message = new Message(TaskTopic.TASK_TOPIC.getTopic(),TaskTopic.OIL_PRICE.getTag(),gasOilPriceTask.getId().toString().getBytes());
                    // 定时投递，执行时间
                    message.setDeliverTimeMs(gasOilPriceTask.getStartTime().getTime());
                    SendResult sendResult = rocketMQTemplate.getProducer().send(message);
                    System.out.println(sendResult);
                    // redisUtil.set(MsgTopic.oilPriceTask.getName() + "-" + gasOilPriceTask.getId(), "", time);
                } else {
                    businessHandle(gasOilPriceTask);
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public void businessHandle(BsGasOilPriceTask gasOilPriceTask) {
        // 立刻执行
        gasOilPriceTask.setStartTime(new Date());
        gasOilPriceTask.setStatus(GasTaskStatusEnum.status2.getStatus());
        editData(gasOilPriceTask);

        if (gasOilPriceTask.getPriceType().equals(GasTaskPriceTypeEnum.type1.getStatus())) {
            // 国标价
            // 更新国标价
            gasOilPriceOfficialService.editPrice(gasOilPriceTask.getRegionId(),gasOilPriceTask.getOilPriceZoneId(), gasOilPriceTask.getOilNo(), gasOilPriceTask.getPrice());

            // 更新自建站的国标价
            gasOilPriceOfficialService.refreshGasPriceOfficial(gasOilPriceTask.getRegionId(), gasOilPriceTask.getOilPriceZoneId(), gasOilPriceTask.getOilNo());

        } else if (gasOilPriceTask.getPriceType().equals(GasTaskPriceTypeEnum.type2.getStatus())) {
            // 油站价
            // 查询油品价格
            BsGasOilPrice price = gasOilPriceService.getGasOilPrice(gasOilPriceTask.getMerId(), gasOilPriceTask.getOilNo());
            if (price == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油品价格");
            }
            price.setPriceGun(gasOilPriceTask.getPrice().subtract(price.getGasStationDrop()));
            price.setPriceVip(price.getPriceGun().subtract(price.getPreferentialMargin()));
            gasOilPriceService.editOilPrice(price);
        } else if (gasOilPriceTask.getPriceType().equals(GasTaskPriceTypeEnum.type3.getStatus())) {
            // 平台优惠
            // 查询油品价格
            BsGasOilPrice price = gasOilPriceService.getGasOilPrice(gasOilPriceTask.getMerId(), gasOilPriceTask.getOilNo());
            if (price == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油品价格");
            }
            price.setPreferentialMargin(gasOilPriceTask.getPrice());
            price.setPriceVip(price.getPriceGun().subtract(price.getPreferentialMargin()));
            gasOilPriceService.editOilPrice(price);
        } else if (gasOilPriceTask.getPriceType().equals(GasTaskPriceTypeEnum.type4.getStatus())) {
            // 油站直降
            // 查询油品价格
            BsGasOilPrice price = gasOilPriceService.getGasOilPrice(gasOilPriceTask.getMerId(), gasOilPriceTask.getOilNo());
            if (price == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到油品价格");
            }
            price.setGasStationDrop(gasOilPriceTask.getPrice());
            price.setPriceGun(price.getPriceOfficial().subtract(price.getGasStationDrop()));
            price.setPriceVip(price.getPriceGun().subtract(price.getPreferentialMargin()));
            gasOilPriceService.editOilPrice(price);
        }

    }

    @Override
    public BsGasOilPriceTask getDetailById(Long taskId) {
        return gasOilPriceTaskMapper.selectByPrimaryKey(taskId);
    }

    @Override
    public void delTask(Long taskId) {
        // 查询价格任务
        BsGasOilPriceTask detail = getDetailById(taskId);
        if (detail == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到任务");
        }
        if (!detail.getStatus().equals(GasTaskStatusEnum.status1.getStatus())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "任务当前状态无法删除");
        }
        detail.setStatus(GasTaskStatusEnum.status0.getStatus());
        editData(detail);

        // 从redis中删除任务
        redisUtil.del(MsgTopic.oilPriceTask.getName() + "-" + taskId);
    }

    @Override
    public List<BsGasOilPriceTask> getTaskList(Map<String, Object> param) {
        BsGasOilPriceTaskExample example = new BsGasOilPriceTaskExample();
        BsGasOilPriceTaskExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(GasTaskStatusEnum.status0.getStatus());

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

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

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

        if (MapUtils.getString(param, "merNoList") != null) {
            criteria.andMerNoIn(Arrays.stream(MapUtils.getString(param, "merNoList").split(",")).collect(Collectors.toList()));
        }

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

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

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

        if (StringUtils.isNotBlank(MapUtils.getString(param, "oilNo"))) {
            criteria.andOilNoEqualTo(MapUtils.getString(param, "oilNo"));
        }

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

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

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

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