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


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.material.stock.WebsitStockDTO;
import com.gree.mall.manager.bean.material.stock.WorkerStockDTO;
import com.gree.mall.manager.bean.websit.WebsitSalesRetAddUP;
import com.gree.mall.manager.bean.websit.WebsitSalesRetDetail;
import com.gree.mall.manager.bean.websit.WebsitSalesRetVO;
import com.gree.mall.manager.commonmapper.WebsitSalesRetCMapper;
import com.gree.mall.manager.enums.IsYesNoEnum;
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.engin.WebsitGoodsMangerLogic;
import com.gree.mall.manager.logic.material.stock.MaterialGoodsStockLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.WebsitSalesItemService;
import com.gree.mall.manager.plus.service.WebsitSalesRetItemService;
import com.gree.mall.manager.plus.service.WebsitSalesRetService;
import com.gree.mall.manager.plus.service.WebsitSalesService;
import com.gree.mall.manager.utils.StringUtil;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


@Service
public class WebsitSalesRetLogic {
    @Autowired
    WebsitSalesRetCMapper websitSalesRetCMapper;

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    WebsitSalesRetItemService websitSalesRetItemService;

    @Autowired
    WebsitSalesRetService websitSalesRetService;

    @Autowired
    MaterialGoodsStockLogic materialGoodsStockLogic;

    @Autowired
    WebsitSalesService websitSalesService;

    @Autowired
    WebsitSalesItemService websitSalesItemService;

    @Autowired
    WebsitGoodsMangerLogic websitGoodsMangerLogic;

    public IPage<WebsitSalesRetVO> pageV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> companyWechatIds = adminUser.getCompanyWechatIds();

        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean, WebsitSalesRetVO.class, adminUser);


        IPage<WebsitSalesRetVO> websitSalesRetVOIPage = websitSalesRetCMapper.pageV2(new Page(zfireParamBean.getPageNum(),
                        zfireParamBean.getPageSize()),
                zfireParam
                , companyWechatIds);

        return websitSalesRetVOIPage;
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(WebsitSalesRetAddUP websitSalesRetAddUP) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (StringUtils.isBlank(websitSalesRetAddUP.getStorageId())) {
            throw new RemoteServiceException("请选择退货仓库");
        }

        final Integer count = websitSalesRetService.lambdaQuery()
                .eq(WebsitSalesRet::getSalesId, websitSalesRetAddUP.getSalesId())
                .isNull(WebsitSalesRet::getConfirmBy)
                .count();

        if (count > 0) {
            throw new RemoteServiceException(websitSalesRetAddUP.getSalesId() + "销售订单发现未处理的退货单，请先处理");
        }

        WebsitSales websitSales = websitSalesService.getById(websitSalesRetAddUP.getSalesId());
        if (!websitSales.getFlag().equals("PAY_TAKE"))
            throw new RemoteServiceException("未提货不能退货");
        websitSalesRetAddUP.setPayType(websitSales.getPayType());
        websitSalesRetAddUP.setWorkerWebsitId(websitSales.getWorkerWebsitId());
        websitSalesRetAddUP.setWorkerWebsitName(websitSales.getWorkerWebsitName());
        websitSalesRetAddUP.setPayNo(websitSales.getPayNo());
        websitSalesRetAddUP.setTotalAmount(websitSales.getTotalAmount());
        websitSalesRetAddUP.setPayTime(websitSales.getPayTime());
        websitSalesRetAddUP.setSalesRetId("TF" + IdWorker.getIdStr());
        websitSalesRetAddUP.setCompanyWechatId(adminUser.getCompanyWechatId());
        websitSalesRetAddUP.setCompanyName(adminUser.getCompanyName());
        websitSalesRetAddUP.setBuyPeople(websitSales.getBuyPeople());
        websitSalesRetAddUP.setSalesType(websitSales.getSalesType());
        websitSalesRetAddUP.setOrderEnginBaseId(websitSales.getOrderEnginBaseId());
        websitSalesRetAddUP.setProjectNo(websitSales.getProjectNo());
        websitSalesRetAddUP.setProjectName(websitSales.getProjectName());
        websitSalesRetAddUP.insert();

        BigDecimal allAmount = new BigDecimal("0");

        if (CollectionUtils.isEmpty(websitSalesRetAddUP.getWebsitSalesRetItems()))
            throw new RemoteServiceException("没有产品不能提交");

        for (WebsitSalesRetItem websitSalesRetItem : websitSalesRetAddUP.getWebsitSalesRetItems()) {
            websitSalesRetItem.setId(null);

            WebsitSalesItem salesItem = websitSalesItemService.lambdaQuery().eq(WebsitSalesItem::getSalesId, websitSales.getSalesId())
                    .eq(WebsitSalesItem::getGoodsId, websitSalesRetItem.getGoodsId()).last("limit 1")
                    .one();

            if (websitSalesRetItem.getRetQty().doubleValue() < 1)
                throw new RemoteServiceException("销售数量不能小于1");


            salesItem.setRetQty(salesItem.getRetQty().add(websitSalesRetItem.getRetQty()));

            if (salesItem.getRetQty().doubleValue() > salesItem.getSalesQty().doubleValue()) {
                throw new RemoteServiceException(websitSalesRetItem.getGoodsName() + "超过销售数量");
            }

            this.checkConvertRetQty(salesItem, websitSalesRetItem);

            salesItem.updateById();

            websitSales.setRetAmount(websitSales.getRetAmount()
                    .add(websitSalesRetItem.getRetQty().multiply(websitSalesRetItem.getPrice())));

            websitSales.updateById();
            websitSalesRetItem.setSalesRetId(websitSalesRetAddUP.getSalesRetId());
            websitSalesRetItem.setGoodsStockUnit(salesItem.getGoodsStockUnit());
            websitSalesRetItem.setConvertQty(salesItem.getConvertQty());
            websitSalesRetItem.setExamineQty(websitSalesRetItem.getRetQty());
            if (websitSalesRetItem.getSaleAmount() != null)
                allAmount = allAmount.add(websitSalesRetItem.getRetQty().multiply(websitSalesRetItem.getPrice()));
        }
        websitSalesRetAddUP.setRetAmount(allAmount);
        websitSalesRetAddUP.updateById();
        websitSalesRetItemService.saveBatch(websitSalesRetAddUP.getWebsitSalesRetItems());
    }

    private void checkConvertRetQty(WebsitSalesItem salesItem, WebsitSalesRetItem websitSalesRetItem) {
        // 退货单明细退货转换数量
        BigDecimal retConvertQty = websitSalesRetItem.getRetQty();
        websitSalesRetItem.setRetConvertQty(retConvertQty);
        websitSalesRetItem.setWorkerGoodsId(salesItem.getWorkerGoodsId());
        websitSalesRetItem.setWorkerGoodsName(salesItem.getWorkerGoodsName());

        if (!salesItem.getGoodsStockUnit().equals(salesItem.getGoodsSalesUnit())) {
            retConvertQty = websitSalesRetItem.getRetQty().divide(salesItem.getGoodsSalesConvertQty(), 1, BigDecimal.ROUND_UP);
            websitSalesRetItem.setRetConvertQty(retConvertQty);
        }

        if (salesItem.getRetQty().compareTo(salesItem.getSalesQty()) >= 0) {
            // 退货数量大于等于销售数量，全退转换数量, 用销售单的转换数量减已退转换数量=剩余可退数量
            final BigDecimal remainQty = salesItem.getConvertQty().subtract(salesItem.getConvertRetQty());
            salesItem.setConvertRetQty(salesItem.getConvertQty());
            websitSalesRetItem.setRetConvertQty(remainQty);
        } else {
            // 历史退货转换数量加上本次退货转换数量
            salesItem.setConvertRetQty(salesItem.getConvertRetQty().add(retConvertQty));
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void update(WebsitSalesRetAddUP websitSalesRetAddUP) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        WebsitSalesRet oldRet = websitSalesRetService.getById(websitSalesRetAddUP.getSalesRetId());
        if (StringUtils.isBlank(websitSalesRetAddUP.getSalesId())) {
            websitSalesRetAddUP.setSalesId(oldRet.getSalesId());
        }

        WebsitSales oldWebsitSales = websitSalesService.getById(websitSalesRetAddUP.getSalesId());
        if (Objects.isNull(oldWebsitSales)) {
            throw new RemoteServiceException("销售单不存在");
        }

        websitSalesRetAddUP.setCompanyWechatId(adminUser.getCompanyWechatId());
        websitSalesRetAddUP.setCompanyName(adminUser.getCompanyName());
        websitSalesRetAddUP.setPayType(oldWebsitSales.getPayType());
        websitSalesRetAddUP.updateById();


        if (!StringUtil.isEmpty(websitSalesRetAddUP.getRetState()) && websitSalesRetAddUP.getRetState().equals("OK")) {
            if (StringUtils.isBlank(oldRet.getStorageId())) {
                throw new RemoteServiceException("请选择退货仓库");
            }

            websitSalesRetAddUP.setRetTime(new Date());
            websitSalesRetAddUP.updateById();

            this.refundOk(websitSalesRetAddUP.getSalesRetId());

            if (websitSalesRetAddUP.getPayType().equals(PayTypeEnum.CASH.getKey())) {
                this.refundAddPayOrder(websitSalesRetAddUP.getSalesRetId());
            }
            websitSalesRetAddUP.setConfirmTime(new Date());
            websitSalesRetAddUP.setConfirmBy(adminUser.getNickName());
            websitSalesRetAddUP.updateById();

            WebsitSalesRet websitSales = websitSalesRetService.getById(websitSalesRetAddUP.getSalesRetId());

            if (websitSales.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())) {
                websitGoodsMangerLogic.givePrice((websitSales.getRetAmount().multiply(new BigDecimal("-1"))),
                        websitSales.getOrderEnginBaseId(), null, "退货金额记录，退货单号：" + websitSales.getSalesRetId(), websitSales.getSalesRetId(), websitSales.getGoodsType());
                websitGoodsMangerLogic.upManage(websitSales.getOrderEnginBaseId(), websitSales.getGoodsType());
            }
            return;
        }

        if (CollectionUtils.isEmpty(websitSalesRetAddUP.getWebsitSalesRetItems()))
            throw new RemoteServiceException("没有产品不能提交");

        BigDecimal allAmount = new BigDecimal("0");
//        websitSalesRetItemService.lambdaUpdate().eq(WebsitSalesRetItem::getSalesRetId, websitSalesRetAddUP.getSalesRetId()).remove();
        final List<WebsitSalesRetItem> retItems = websitSalesRetItemService.lambdaQuery()
                .eq(WebsitSalesRetItem::getSalesRetId, websitSalesRetAddUP.getSalesRetId())
                .list();
        for (WebsitSalesRetItem websitSalesRetItem : retItems) {
//            websitSalesRetItem.setId(null);
//            websitSalesRetItem.setSalesRetId(websitSalesRetAddUP.getSalesRetId());
//            websitSalesRetItem.setConvertQty(websitSalesRetItem.getRetQty());
//            websitSalesRetItem.setExamineQty(websitSalesRetItem.getRetQty());
            allAmount = allAmount.add(websitSalesRetItem.getRetQty().multiply(websitSalesRetItem.getSaleAmount()));
        }
        websitSalesRetAddUP.setRetAmount(allAmount);
        websitSalesRetAddUP.setSalesType(oldWebsitSales.getSalesType());
        websitSalesRetAddUP.setOrderEnginBaseId(oldWebsitSales.getOrderEnginBaseId());
        websitSalesRetAddUP.setProjectNo(oldWebsitSales.getProjectNo());
        websitSalesRetAddUP.setProjectName(oldWebsitSales.getProjectName());
        websitSalesRetAddUP.updateById();
        websitSalesRetItemService.saveBatch(websitSalesRetAddUP.getWebsitSalesRetItems());
    }

    private void refundAddPayOrder(String salesRetId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        WebsitSalesRet websitSalesRet = websitSalesRetService.getById(salesRetId);

        List<WebsitSalesRetItem> websitSalesRetItemList = websitSalesRetItemService.lambdaQuery().eq(WebsitSalesRetItem::getSalesRetId, salesRetId).list();

        WebsitSalesPayOrder websitSalesPayOrder = new WebsitSalesPayOrder();

        WebsitSalesPayOrder order = new WebsitSalesPayOrder();
        order.setCompanyWechatId(websitSalesRet.getCompanyWechatId());
        order.setCompanyWechatName(websitSalesRet.getCompanyName());
        order.setGoodsType(websitSalesRet.getGoodsType());
        order.setWebsitId(websitSalesRet.getWebsitId());
        order.setWebsitName(websitSalesRet.getWebsitName());
        order.setOrderId(websitSalesRet.getSalesRetId());
        order.setOriginOrderId(websitSalesRet.getSalesId());
        order.setOrderCreateTime(websitSalesRet.getCreateTime());
        order.setPayType(websitSalesRet.getPayType());
        order.setPayFlag(IsYesNoEnum.YES.getKey());
        order.setPayTime(websitSalesRet.getRetTime());
        order.setPayValue(websitSalesRet.getRetAmount());
        order.setOrderType(PayOrderTypeEnum.R.getKey());
        order.setOrderSource(SalesPayOrderSourceEnum.SALES_RET.getKey());
        order.insert();
    }


    private void refundOk(String salesRetId) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        WebsitSalesRet websitSalesRet = websitSalesRetService.getById(salesRetId);

        List<WebsitSalesRetItem> websitSalesRetItemList = websitSalesRetItemService.lambdaQuery().eq(WebsitSalesRetItem::getSalesRetId, salesRetId).list();

        List<WorkerStockDTO> workerStockDTOS = new ArrayList<>();
        List<WebsitStockDTO> websitStockDTOS = new ArrayList<>();
        for (WebsitSalesRetItem websitSalesRetItem : websitSalesRetItemList) {
            if (StringUtils.isNotBlank(websitSalesRetItem.getWorkerGoodsId())) {
                WorkerStockDTO workerStockDTO = new WorkerStockDTO();
                workerStockDTO.setCompanyWechatId(websitSalesRet.getCompanyWechatId());
                workerStockDTO.setCompanyWechatName(websitSalesRet.getCompanyName());
                workerStockDTO.setIdentity(websitSalesRet.getIdentity());
                workerStockDTO.setWorkerId(websitSalesRet.getWorkerId());
                workerStockDTO.setWorkerName(websitSalesRet.getWorkerName());
                workerStockDTO.setWebsitId(websitSalesRet.getWebsitId());
                workerStockDTO.setWebsitName(websitSalesRet.getWebsitName());
                workerStockDTO.setSdate(websitSalesRet.getCreateTime());
                workerStockDTO.setWorkerWebsitId(websitSalesRet.getWorkerWebsitId());
                workerStockDTO.setWorkerWebsitName(websitSalesRet.getWorkerWebsitName());
                workerStockDTO.setWebsitGoodsId(websitSalesRetItem.getGoodsId());
                workerStockDTO.setWebsitGoodsName(websitSalesRetItem.getGoodsName());
                workerStockDTO.setWebsitGoodsPrice(websitSalesRetItem.getPrice());
                workerStockDTO.setWebsitGoodsQty(websitSalesRetItem.getRetQty());
                workerStockDTO.setGoodsType(websitSalesRetItem.getGoodsType());
                workerStockDTO.setPrice(websitSalesRetItem.getConvertPrice());
                workerStockDTO.setGoodsStockUnit(websitSalesRetItem.getGoodsSalesUnit());
                workerStockDTO.setGoodsSalesConvertQty(websitSalesRetItem.getGoodsSalesConvertQty());
                workerStockDTO.setGoodsSpecification(websitSalesRetItem.getGoodsSpecification());
                workerStockDTO.setGoodsId(websitSalesRetItem.getWorkerGoodsId());
                workerStockDTO.setGoodsName(websitSalesRetItem.getWorkerGoodsName());
                workerStockDTO.setRef(websitSalesRet.getSalesRetId());
                workerStockDTO.setRefType("销售退货单");
                workerStockDTO.setPartsAttr(PartsAttrEnum.NEW.getKey());
                workerStockDTO.setChangeQty(websitSalesRetItem.getRetConvertQty());
                workerStockDTO.setDirectFlag(DirectFlagEnum.SUB.getKey());
                workerStockDTO.setFlag(WorkerStockFlagEnum.REFUND.getKey());
                workerStockDTO.setObj("师傅");
                workerStockDTO.setWorkerOrderNo("");
                workerStockDTO.setRemark(websitSalesRet.getRemark());
                workerStockDTO.setOperateBy(adminUser.getNickName());
                workerStockDTO.setOperateTime(DateUtil.date());
                workerStockDTOS.add(workerStockDTO);
            }

            // 入库注值
            WebsitStockDTO websitStockDTO = new WebsitStockDTO();
            websitStockDTO.setCompanyWechatId(websitSalesRet.getCompanyWechatId());
            websitStockDTO.setCompanyWechatName(websitSalesRet.getCompanyName());
            websitStockDTO.setWebsitId(websitSalesRet.getWebsitId());
            websitStockDTO.setWebsitName(websitSalesRet.getWebsitName());
            websitStockDTO.setSdate(websitSalesRet.getCreateTime());
            websitStockDTO.setPartsAttr(PartsAttrEnum.NEW.toString());
            websitStockDTO.setGoodsId(websitSalesRetItem.getGoodsId());
            websitStockDTO.setGoodsName(websitSalesRetItem.getGoodsName());
            websitStockDTO.setGoodsType(websitSalesRetItem.getGoodsType());
            websitStockDTO.setPrice(websitSalesRetItem.getPrice());
            websitStockDTO.setRef(websitSalesRet.getSalesRetId());
            websitStockDTO.setRefType("销售退货单");
            websitStockDTO.setChangeQty(websitSalesRetItem.getRetQty());
            websitStockDTO.setDirectFlag(DirectFlagEnum.ADD.getKey());
            websitStockDTO.setRemark(websitSalesRet.getRemark());
            websitStockDTO.setOperateBy(adminUser.getNickName());
            websitStockDTO.setOperateTime(new Date());
            websitStockDTO.setObj("师傅");
            websitStockDTO.setStorageId(websitSalesRet.getStorageId());
            websitStockDTOS.add(websitStockDTO);
        }

        materialGoodsStockLogic.handleWebsitStock(websitStockDTOS);
        if (websitSalesRet.getBuyPeople().equals(BuyPeopleEnum.WORKER.getKey())
                && CollectionUtil.isNotEmpty(workerStockDTOS)) {
            materialGoodsStockLogic.handleWorkerStock(workerStockDTOS);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void del(List<String> salesRetId) {

        websitSalesRetService.lambdaUpdate().in(WebsitSalesRet::getSalesRetId, salesRetId).remove();
        websitSalesRetItemService.lambdaUpdate().in(WebsitSalesRetItem::getSalesRetId, salesRetId).remove();
    }

    public WebsitSalesRetDetail detail(String id) {
        WebsitSalesRet websitSalesRet = websitSalesRetService.getById(id);

        WebsitSalesRetDetail websitSalesRetDetail = BeanUtil.toBean(websitSalesRet, WebsitSalesRetDetail.class);

        if (websitSalesRet.getSalesType().equals("工程")) {
            WebsitSales websitSales = websitSalesService.lambdaQuery()
                    .eq(WebsitSales::getSalesId, websitSalesRet.getSalesId())
                    .one();

            websitSalesRetDetail.setManger(websitSales.getManger());
            websitSalesRetDetail.setMobile(websitSales.getMobile());
            websitSalesRetDetail.setStartTime(websitSales.getStartTime());
            websitSalesRetDetail.setEndTime(websitSales.getEndTime());
            websitSalesRetDetail.setProvince(websitSales.getProvince());
            websitSalesRetDetail.setProvinceId(websitSales.getProvinceId());
            websitSalesRetDetail.setCity(websitSales.getCity());
            websitSalesRetDetail.setCityId(websitSales.getCityId());
            websitSalesRetDetail.setArea(websitSales.getArea());
            websitSalesRetDetail.setAreaId(websitSales.getAreaId());
            websitSalesRetDetail.setStreet(websitSales.getStreet());
            websitSalesRetDetail.setStreetId(websitSales.getStreetId());
            websitSalesRetDetail.setAddress(websitSales.getAddress());
        }

        websitSalesRetDetail.setWebsitSalesRetItems(websitSalesRetItemService.lambdaQuery().eq(WebsitSalesRetItem::getSalesRetId, id).list());
        return websitSalesRetDetail;
    }
}
