package com.gree.mall.manager.logic.material.manage;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
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.material.manage.WebsitPartsChangeSalesBean;
import com.gree.mall.manager.bean.material.manage.WebsitPartsChangeSalesVO;
import com.gree.mall.manager.bean.material.stock.WorkerStockDTO;
import com.gree.mall.manager.commonmapper.MaterialMapper;
import com.gree.mall.manager.enums.IsEnum;
import com.gree.mall.manager.enums.base.BaseEnum;
import com.gree.mall.manager.enums.material.*;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.material.stock.MaterialGoodsStockLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class WebsitPartsChangeSalesLogic {

    private final CommonLogic commonLogic;
    private final MaterialMapper materialMapper;
    private final WebsitPartsChangeSalesService websitPartsChangeSalesService;
    private final WebsitPartsChangeSalesItemService websitPartsChangeSalesItemService;
    private final AdminWebsitService adminWebsitService;
    private final WebsitPartsRefundConfigService websitPartsRefundConfigService;
    private final WebsitPartsSalesService websitPartsSalesService;
    private final MaterialGoodsStockLogic materialGoodsStockLogic;

    public IPage<WebsitPartsChangeSalesVO> pageList(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.materialParam(zfireParamBean, WebsitPartsChangeSalesVO.class, adminUser);

        return materialMapper.websitPurchaseChangeSalesPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }

    public WebsitPartsChangeSalesBean detail(String changeSalesNo) {
        WebsitPartsChangeSales partsChangeSales = websitPartsChangeSalesService.lambdaQuery()
                .eq(WebsitPartsChangeSales::getChangeSalesNo, changeSalesNo)
                .one();
        WebsitPartsChangeSalesBean partsChangeSalesBean = new WebsitPartsChangeSalesBean();
        BeanUtils.copyProperties(partsChangeSales, partsChangeSalesBean);

        List<WebsitPartsChangeSalesItem> partsChangeSalesItems = websitPartsChangeSalesItemService.lambdaQuery()
                .eq(WebsitPartsChangeSalesItem::getChangeSalesNo, changeSalesNo)
                .list();

        partsChangeSalesBean.setPartsChangeSalesItemList(partsChangeSalesItems);
        return partsChangeSalesBean;
    }

    @Transactional
    public void examine(String changeSalesNo, String flag, String examineRemark) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitPartsChangeSales partsChangeSales = websitPartsChangeSalesService.getById(changeSalesNo);
        if (!partsChangeSales.getFlag().equals(PartsOrderFlagEnum.SUBMIT.getKey())) {
            throw new RemoteServiceException(changeSalesNo + "单据状态："
                    + BaseEnum.keyToValue(PartsOrderFlagEnum.class, partsChangeSales.getFlag()) + "，失败");
        }

        if (!(PartsOrderFlagEnum.AGREE.getKey() + "|" + PartsOrderFlagEnum.REJECT.getKey()).contains(flag)) {
            throw new RemoteServiceException("状态不正确");
        }

        partsChangeSales.setExamineRemark(examineRemark)
                .setFlag(flag)
                .setExamineBy(adminUser.getNickName())
                .setExamineTime(DateUtil.date());
        // 更新
        partsChangeSales.updateById();

        List<WebsitPartsChangeSalesItem> partsChangeSalesItems = websitPartsChangeSalesItemService.lambdaQuery()
                .eq(WebsitPartsChangeSalesItem::getChangeSalesNo, changeSalesNo)
                .list();

        if (flag.equals(PartsOrderFlagEnum.AGREE.getKey())) {
            // 审核通过 师傅临占库存减 转销售库存加
            List<WorkerStockDTO> workerStockDTOList = this.createWorkerStockDTO(partsChangeSales, partsChangeSalesItems, PartsRefTypeEnum.CHANGE_SALES.getRemark(),
                    PartsAttrEnum.TEMP_NEW.getKey(), PartsAttrEnum.CHANGE_NEW.getKey());
            materialGoodsStockLogic.handleWorkerStock(workerStockDTOList);
        } else {
            // 审核驳回时处理方法
            this.rejectMethod(partsChangeSales, partsChangeSalesItems, examineRemark);
        }
    }

    private void rejectMethod(WebsitPartsChangeSales partsChangeSales, List<WebsitPartsChangeSalesItem> partsChangeSalesItems, String examineRemark) throws Exception {
        AdminWebsit shop = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, partsChangeSales.getCompanyWechatId())
                .eq(AdminWebsit::getWebsitId, partsChangeSales.getWebsitId())
                .eq(AdminWebsit::getPartsWebsitId, partsChangeSales.getPartsWebsitId())
                .one();
        WebsitPartsRefundConfig oneConfig = websitPartsRefundConfigService.lambdaQuery()
                .eq(WebsitPartsRefundConfig::getCompanyWechatId, partsChangeSales.getCompanyWechatId())
                .eq(WebsitPartsRefundConfig::getIsDefault, IsEnum.Y.getValue())
                .one();
        WebsitPartsRefundConfig partsConfig = websitPartsRefundConfigService.lambdaQuery()
                .eq(WebsitPartsRefundConfig::getCompanyWechatId, partsChangeSales.getCompanyWechatId())
                .eq(WebsitPartsRefundConfig::getWebsitId, partsChangeSales.getWebsitId())
                .one();
        if (Objects.isNull(shop) || Objects.isNull(shop.getPartsWebsitAttr())) {
            throw new RemoteServiceException("网点信息异常！操作失败");
        }
        // 超期时间
        Integer expire;
        if (shop.getPartsWebsitAttr()) {
            // 内区天数
            expire = Objects.isNull(partsConfig) ? oneConfig.getNewRefundInner() : partsConfig.getNewRefundInner();
        } else {
            // 外区天数
            expire = Objects.isNull(partsConfig) ? oneConfig.getNewRefundOutside() : partsConfig.getNewRefundOutside();
        }

        // 更新销售单下推标志和流程结束时间
        DateTime offsetDateTime = DateUtil.offset(DateUtil.date(), DateField.DAY_OF_MONTH, expire);
        boolean update = websitPartsSalesService.lambdaUpdate()
                .set(WebsitPartsSales::getEndTime, offsetDateTime)
                .set(WebsitPartsSales::getPushFlag, PartsPushFlagEnum.SALES.getKey())
                .eq(WebsitPartsSales::getId, partsChangeSales.getSalesId())
                .eq(WebsitPartsSales::getPushFlag, PartsPushFlagEnum.TRANS.getKey())
                .update();

        if (!update) {
            throw new RemoteServiceException("更新销售单下推标志和流程结束时间失败");
        }

        // 更新销售单明细下推标志
        materialMapper.updateItemPushFlag(partsChangeSales.getSalesId(), PartsPushFlagEnum.SALES.getKey());

        // 保存销售单流程完结时间
        WebsitPartsSalesRecord partsSalesOrderRecord = new WebsitPartsSalesRecord();
        partsSalesOrderRecord.setSalesId(partsChangeSales.getSalesId())
                .setEndTime(partsChangeSales.getSalesEndTime())
                .setRemark(examineRemark)
                .setCreateTime(DateUtil.date())
                .insert();

        // 审核不通过延期 师傅临占库存减 新件库存加
        List<WorkerStockDTO> workerStockDTOList = this.createWorkerStockDTO(partsChangeSales, partsChangeSalesItems,
                PartsRefTypeEnum.CHANGE_SALES.getRemark(), PartsAttrEnum.TEMP_NEW.getKey(), PartsAttrEnum.NEW.getKey());
        materialGoodsStockLogic.handleWorkerStock(workerStockDTOList);
    }

    private List<WorkerStockDTO> createWorkerStockDTO(WebsitPartsChangeSales partsChangeSales,
                                                      List<WebsitPartsChangeSalesItem> partsChangeSalesItemList,
                                                      String refType, String partsAttr1,
                                                      String partsAttr2) {
        List<WorkerStockDTO> workerStockDTOList = new ArrayList<>();
        if (StringUtils.isNotBlank(partsAttr1)) {
            for (WebsitPartsChangeSalesItem partsChangeSalesItem : partsChangeSalesItemList) {
                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
                workerStockDTO.setCompanyWechatId(partsChangeSales.getCompanyWechatId());
                workerStockDTO.setCompanyWechatName(partsChangeSales.getCompanyWechatName());
                workerStockDTO.setIdentity(partsChangeSales.getIdentity());
                workerStockDTO.setWorkerId(partsChangeSales.getWorkerId());
                workerStockDTO.setWorkerName(partsChangeSales.getWorkerName());
                workerStockDTO.setWebsitId(partsChangeSales.getWebsitId());
                workerStockDTO.setWebsitName(partsChangeSales.getWebsitName());
                workerStockDTO.setPartsWebsitId(partsChangeSales.getPartsWebsitId());
                workerStockDTO.setSdate(DateUtil.date());
                workerStockDTO.setGoodsType(WebsitGoodsTypeEnum.P.getKey());
                workerStockDTO.setGoodsId(partsChangeSalesItem.getPartsNumber());
                workerStockDTO.setGoodsName(partsChangeSalesItem.getPartsName());
                workerStockDTO.setMaterialGroupName(partsChangeSalesItem.getMaterialGroupName());
                workerStockDTO.setGoodsStockUnit(partsChangeSalesItem.getGoodsStockUnit());
                workerStockDTO.setPrice(partsChangeSalesItem.getSalesPrice());
                workerStockDTO.setRef(partsChangeSales.getChangeSalesNo());
                workerStockDTO.setRefType(refType);
                workerStockDTO.setPartsAttr(partsAttr1);
                workerStockDTO.setChangeQty(partsChangeSalesItem.getQty());
                workerStockDTO.setDirectFlag(DirectFlagEnum.SUB.getKey());
                workerStockDTO.setRemark("");
                workerStockDTO.setOperateBy(CommonUtils.getNickName());
                workerStockDTO.setOperateTime(DateUtil.date());

                workerStockDTOList.add(workerStockDTO);
            }
        }
        if (StringUtils.isNotBlank(partsAttr2)) {
            for (WebsitPartsChangeSalesItem partsChangeSalesItem : partsChangeSalesItemList) {
                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
                workerStockDTO.setCompanyWechatId(partsChangeSales.getCompanyWechatId());
                workerStockDTO.setCompanyWechatName(partsChangeSales.getCompanyWechatName());
                workerStockDTO.setIdentity(partsChangeSales.getIdentity());
                workerStockDTO.setWorkerId(partsChangeSales.getWorkerId());
                workerStockDTO.setWorkerName(partsChangeSales.getWorkerName());
                workerStockDTO.setWebsitId(partsChangeSales.getWebsitId());
                workerStockDTO.setWebsitName(partsChangeSales.getWebsitName());
                workerStockDTO.setPartsWebsitId(partsChangeSales.getPartsWebsitId());
                workerStockDTO.setSdate(DateUtil.date());
                workerStockDTO.setGoodsType(WebsitGoodsTypeEnum.P.getKey());
                workerStockDTO.setGoodsId(partsChangeSalesItem.getPartsNumber());
                workerStockDTO.setGoodsName(partsChangeSalesItem.getPartsName());
                workerStockDTO.setMaterialGroupName(partsChangeSalesItem.getMaterialGroupName());
                workerStockDTO.setGoodsStockUnit(partsChangeSalesItem.getGoodsStockUnit());
                workerStockDTO.setPrice(partsChangeSalesItem.getSalesPrice());
                workerStockDTO.setRef(partsChangeSalesItem.getChangeSalesNo());
                workerStockDTO.setRefType(refType);
                workerStockDTO.setPartsAttr(partsAttr2);
                workerStockDTO.setChangeQty(partsChangeSalesItem.getQty());
                workerStockDTO.setDirectFlag(DirectFlagEnum.ADD.getKey());
                workerStockDTO.setRemark("");
                workerStockDTO.setOperateBy(CommonUtils.getNickName());
                workerStockDTO.setOperateTime(DateUtil.date());

                workerStockDTOList.add(workerStockDTO);
            }
        }
        return workerStockDTOList;
    }
}
