package com.gree.mall.manager.logic.order;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.listvo.order.PunishOrderVO;
import com.gree.mall.manager.bean.listvo.param.ExamineZfireParamBean;
import com.gree.mall.manager.bean.order.PunishOrderBean;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.ExamineStatusEnum;
import com.gree.mall.manager.enums.workorder.ExamineProjectTypeEnum;
import com.gree.mall.manager.enums.workorder.SettleNormTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.PgOrderBaseService;
import com.gree.mall.manager.plus.service.PunishOrderProductService;
import com.gree.mall.manager.plus.service.PunishOrderService;
import com.gree.mall.manager.plus.service.PunishOrderWorkerService;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 处罚单
 *
 * @author ：lijh
 * @description：TODO
 * @date ：2024/2/29 12:52
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class PunishOrderLogic {
    private final CommonLogic commonLogic;
    private final PunishOrderService punishOrderService;
    private final PunishOrderWorkerService punishOrderWorkerService;
    private final PunishOrderProductService punishOrderProductService;
    private final CommonMapper commonMapper;
    private final PgOrderBaseService pgOrderBaseService;

    /**
     * 处罚工单列表
     *
     * @param zfireParamBean
     * @return
     */
    public IPage<PunishOrderVO> list(ExamineZfireParamBean zfireParamBean) {
        FieldUtils.supplyParam(zfireParamBean, PunishOrderVO.class, commonLogic.getAdminUser());
        IPage<PunishOrderVO> page = commonMapper.punishOrderList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        return page;
    }


    /**
     * 保存处罚工单
     */
    @Transactional
    public void save(PunishOrderBean punishOrderBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (CollectionUtils.isEmpty(punishOrderBean.getPunishOrderProducts())) {
            throw new RemoteServiceException("产品信息不能为空");
        }
        if (CollectionUtils.isEmpty(punishOrderBean.getPunishOrderWorkers())) {
            throw new RemoteServiceException("处罚工程师信息不能为空");
        }
        if (StringUtils.isNotBlank(punishOrderBean.getId())) {
            PunishOrder old = punishOrderService.getById(punishOrderBean.getId());
            if (!StringUtils.equals(old.getStatus(), ExamineStatusEnum.SAVE.getKey())) {
                throw new RemoteServiceException("非保存状态不可编辑");
            }
        } else {
            List<String> insideCodes = punishOrderBean.getPunishOrderProducts().stream().map(PunishOrderProduct::getInsideCode).collect(Collectors.toList());
            List<String> outCodes = punishOrderBean.getPunishOrderProducts().stream().map(PunishOrderProduct::getOutCode).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(insideCodes)) {
                //检查条码是否已存在
                Integer count = punishOrderProductService.lambdaQuery()
                        .in(PunishOrderProduct::getInsideCode, insideCodes)
                        .eq(PunishOrderProduct::getCompanyWechatId, adminUser.getCompanyWechatId()).count();
                if (count > 0) {
                    throw new RemoteServiceException("内机条码已存在");
                }
            }
            if (!CollectionUtils.isEmpty(outCodes)) {
                //检查条码是否已存在
                Integer count = punishOrderProductService.lambdaQuery()
                        .in(PunishOrderProduct::getOutCode, outCodes)
                        .eq(PunishOrderProduct::getCompanyWechatId, adminUser.getCompanyWechatId()).count();
                if (count > 0) {
                    throw new RemoteServiceException("外机条码已存在");
                }
            }
        }
        long count = punishOrderBean.getPunishOrderWorkers().stream().filter(v -> v.getAmount() == null || v.getAmount().doubleValue() < 0).count();
        if (count > 0) {
            throw new RemoteServiceException("处罚金额不能为空或小于0");
        }
        //总处罚金额
        BigDecimal totalAmount = punishOrderBean.getPunishOrderWorkers().stream().map(PunishOrderWorker::getAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);

        punishOrderBean.setTotalAmount(totalAmount);
        punishOrderBean.setCompanyWechatId(adminUser.getCompanyWechatId());
        punishOrderBean.setCompanyWechatName(adminUser.getCompanyName());
        punishOrderService.saveOrUpdate(punishOrderBean);
        //产品信息
        punishOrderProductService.lambdaUpdate().eq(PunishOrderProduct::getPunishOrderId, punishOrderBean.getId()).remove();
        punishOrderBean.getPunishOrderProducts().forEach(v -> v
                .setPunishOrderId(punishOrderBean.getId())
                .setCompanyWechatId(adminUser.getCompanyWechatId())
                .setCompanyWechatName(adminUser.getCompanyName())
        );
        punishOrderProductService.saveBatch(punishOrderBean.getPunishOrderProducts());
        //处罚的工程师信息
        punishOrderWorkerService.lambdaUpdate().eq(PunishOrderWorker::getPunishOrderId, punishOrderBean.getId()).remove();
        punishOrderBean.getPunishOrderWorkers().forEach(v -> v
                .setPunishOrderId(punishOrderBean.getId())
                .setCompanyWechatId(adminUser.getCompanyWechatId())
                .setCompanyWechatName(adminUser.getCompanyName())
        );
        punishOrderWorkerService.saveBatch(punishOrderBean.getPunishOrderWorkers());
    }


    /**
     * 详情
     *
     * @param id
     * @return
     */
    public PunishOrderBean detail(String id) {
        PunishOrder punishOrder = punishOrderService.getById(id);
        PunishOrderBean punishOrderBean = BeanUtil.copyProperties(punishOrder, PunishOrderBean.class);
        //产品信息
        punishOrderBean.setPunishOrderProducts(punishOrderProductService.lambdaQuery().eq(PunishOrderProduct::getPunishOrderId, id).list());
        //处罚的工程师信息
        punishOrderBean.setPunishOrderWorkers(punishOrderWorkerService.lambdaQuery().eq(PunishOrderWorker::getPunishOrderId, id).list());
        return punishOrderBean;
    }


    /**
     * 删除
     *
     * @param id
     */
    @Transactional
    public void delete(String id) {
        punishOrderService.lambdaUpdate().eq(PunishOrder::getId, id).remove();
        punishOrderProductService.lambdaUpdate().eq(PunishOrderProduct::getPunishOrderId, id).remove();
        punishOrderWorkerService.lambdaUpdate().eq(PunishOrderWorker::getPunishOrderId, id).remove();
    }

    /**
     * 审批
     *
     * @param id
     * @param examineStatus
     * @param examineRemark
     */
    @Transactional
    public void examine(String id, ExamineStatusEnum examineStatus, String examineRemark) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        PunishOrder punishOrder = punishOrderService.getById(id);
        List<PunishOrderWorker> punishOrderWorkers = punishOrderWorkerService.lambdaQuery().eq(PunishOrderWorker::getPunishOrderId, id).list();
        if (!punishOrder.getStatus().equals(ExamineStatusEnum.SAVE.getKey())) {
            throw new RemoteServiceException("非已保存状态不可审批");
        }
        punishOrder.setStatus(examineStatus.getKey());
        punishOrder.setExamineRemark(examineRemark);
        punishOrder.setExamineBy(adminUser.getNickName());
        punishOrder.setExamineTime(new Date());
        punishOrder.updateById();

        if (!StringUtils.equals(examineStatus.getKey(), ExamineStatusEnum.OK.getKey())) {
            return;
        }
        PgOrderBase orderBase = pgOrderBaseService.getById(punishOrder.getOrderBaseId());

        //处罚记录(处罚)
        for (PunishOrderWorker punishOrderWorker : punishOrderWorkers) {
            // 插入结算单
            PgSettleOrder order = converPgSettleOrder(punishOrder, orderBase);
            order.setWorkerName(punishOrderWorker.getWorkerName());
            order.setWorkerMobile(punishOrderWorker.getWorkerMobile());
            order.setWorkerIdcard("");
            order.setSettleOrderType(SettleNormTypeEnum.PUNISH.getKey());
            order.setSettleNum(1);
            //处罚金额保存的时候是正数，结算单需要显示负数，这里处理
            order.setSettleAmount(BigDecimal.ZERO.subtract(punishOrderWorker.getAmount()));
            order.insert();
        }

        //处置记录(奖励)
        if (StringUtils.isNotBlank(punishOrder.getDisposeWorkerName())) {
            PgSettleOrder order2 = converPgSettleOrder(punishOrder, orderBase);
            order2.setWorkerName(punishOrder.getDisposeWorkerName());
            order2.setWorkerMobile(punishOrder.getDisposeWorkerMobile());
            order2.setWorkerIdcard("");
            order2.setSettleOrderType(SettleNormTypeEnum.PUNISH.getKey());
            order2.setSettleNum(1);
            order2.setSettleAmount(punishOrder.getTotalAmount());
            order2.insert();
        }
    }


    public PgSettleOrder converPgSettleOrder(PunishOrder punishOrder, PgOrderBase orderBase) {
        PgSettleOrder order = new PgSettleOrder();
        order.setCompanyWechatId(punishOrder.getCompanyWechatId());
        order.setCompanyWechatName(punishOrder.getCompanyWechatName());
        order.setWebsitId(punishOrder.getWebsitId());
        order.setWebsitName(punishOrder.getWebsitName());
        order.setOrderBaseId(punishOrder.getOrderBaseId());
        order.setWorkerId(punishOrder.getDisposeWorkerId());
        order.setCustomerName(punishOrder.getUserName());
        order.setCustomerMobile(punishOrder.getUserMobile());
        order.setCustomerAddress(punishOrder.getAddress());
        order.setOrderType(punishOrder.getOrderSmallType());
        order.setOrderTypeText(punishOrder.getOrderSmallTypeText());
        order.setOrderSmallType(punishOrder.getOrderSmallType());
        order.setOrderSmallTypeText(punishOrder.getOrderSmallTypeText());
        order.setRemark(punishOrder.getRemark());
        order.setPunishOrderId(punishOrder.getId());
        if (orderBase != null) {
            order.setOrderCreateTime(orderBase.getCreateTime());
            order.setWorkerEndTime(orderBase.getOverTime());
            order.setOrderSource(orderBase.getSource());
            order.setOrderChannel(orderBase.getOrderChannelText());
            order.setOrderChannelId(orderBase.getOrderChannelId());
        }
        return order;
    }

}
