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

import cn.hutool.core.collection.CollectionUtil;
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.base.MaterialCategoryTree;
import com.gree.mall.manager.bean.material.base.WebsitNormChargeBean;
import com.gree.mall.manager.bean.material.base.WebsitNormChargeVO;
import com.gree.mall.manager.commonmapper.MaterialMapper;
import com.gree.mall.manager.enums.material.NormTypeEnum;
import com.gree.mall.manager.enums.material.StateEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.common.SysDictCompanyLogic;
import com.gree.mall.manager.plus.entity.SysDictCompany;
import com.gree.mall.manager.plus.entity.WebsitNormCharge;
import com.gree.mall.manager.plus.entity.WebsitNormRela;
import com.gree.mall.manager.plus.service.SysDictCompanyService;
import com.gree.mall.manager.plus.service.WebsitNormChargeService;
import com.gree.mall.manager.plus.service.WebsitNormRelaService;
import com.gree.mall.manager.utils.excel.ExcelUtils;
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 org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class NormChargeLogic {


    private final CommonLogic commonLogic;
    private final MaterialMapper materialMapper;
    private final WebsitNormChargeService websitNormChargeService;
    private final SysDictCompanyService sysDictCompanyService;
    private final SysDictCompanyLogic sysDictCompanyLogic;
    private final MaterialCategoryLogic materialCategoryLogic;
    private final WebsitNormRelaService websitNormRelaService;

    public IPage<WebsitNormChargeVO> page(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.materialParam(zfireParamBean, WebsitNormChargeVO.class, adminUser);
        return materialMapper.websitNormChargePage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }

    public WebsitNormChargeBean detail(String id) {
        WebsitNormCharge websitNormCharge = websitNormChargeService.getById(id);
        WebsitNormChargeBean bean = new WebsitNormChargeBean();
        BeanUtils.copyProperties(websitNormCharge, bean);
        final List<WebsitNormRela> relas = websitNormRelaService.lambdaQuery()
                .eq(WebsitNormRela::getNormId, id)
                .list();
        bean.setItems(relas);
        return bean;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(WebsitNormChargeBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (StringUtils.isBlank(bean.getNormType())) {
            throw new RemoteServiceException("收费类型不能为空");
        }

        bean.setNormId(null);

        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
            bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());
        }

        // 分账检查
        this.checkAmount(bean);
        // 库存单位不为空时,调用添加处理
        this.stockUnitEmptyAdd(bean);

        bean.insert();

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            for (WebsitNormRela item : bean.getItems()) {
                item.setCompanyWechatId(bean.getCompanyWechatId())
                        .setNormId(bean.getNormId());
            }
            websitNormRelaService.saveBatch(bean.getItems());
        }
    }

    private void stockUnitEmptyAdd(WebsitNormCharge goods) {
        if (StringUtils.isNotBlank(goods.getUnit())) {

            String type = "ASSIST_UNIT";
            Integer count = sysDictCompanyService.lambdaQuery()
                    .eq(SysDictCompany::getDictType, type)
                    .eq(SysDictCompany::getDictValue, goods.getUnit())
                    .count();

            if (count == 0) {
                SysDictCompany company = new SysDictCompany();
                company.setDictType(type)
                        .setDictValue(goods.getUnit());
                sysDictCompanyLogic.saveOpenDict(company);
            }
        }
    }

    private void checkAmount(WebsitNormCharge bean) {
        if (Objects.isNull(bean.getNormAmount())) {
            throw new RemoteServiceException("收费标准不能为空");
        }

//        if (Objects.isNull(bean.getSelfWorkerAmount())) {
//            if (bean.getNormType().equals(NormTypeEnum.M.getKey())) {
//                throw new RemoteServiceException("自有库存师傅分账金额不能为空");
//            } else {
//                throw new RemoteServiceException("师傅分账金额不能为空");
//            }
//        }
//
//        if (Objects.isNull(bean.getManualAmount())) {
//            throw new RemoteServiceException("师傅手工费用不能为空");
//        }
//
//        if (bean.getNormType().equals(NormTypeEnum.M.getKey()) && Objects.isNull(bean.getOutWorkerAmount())) {
//            throw new RemoteServiceException("外购辅材师傅分账金额不能为空");
//        }
        // 检查收费标准和分账金额
        if (bean.getNormAmount().compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal selWorkerAmount = BigDecimal.ZERO;
            BigDecimal selWebsitAmount = BigDecimal.ZERO;
//            BigDecimal outWorkerAmount = BigDecimal.ZERO;
//            BigDecimal outWebsitAmount = BigDecimal.ZERO;

//            if (bean.getSelfWorkerAmount().compareTo(BigDecimal.ZERO) > 0) {
//                if (bean.getSelfWorkerAmount().compareTo(bean.getNormAmount()) > 0) {
//                    if (bean.getNormType().equals(NormTypeEnum.M.getKey())) {
//                        throw new RemoteServiceException("自有库存师傅分账金额不能大于收费标准");
//                    } else {
//                        throw new RemoteServiceException("师傅分账金额不能大于收费标准");
//                    }
//                }

//                selWorkerAmount = bean.getSelfWorkerAmount();
                selWorkerAmount = bean.getNormAmount();
                selWebsitAmount = bean.getNormAmount().subtract(selWorkerAmount);
//            } else {
//                selWebsitAmount = bean.getNormAmount();
//            }

//            if (bean.getOutWorkerAmount().compareTo(BigDecimal.ZERO) > 0) {
//                if (bean.getOutWorkerAmount().compareTo(bean.getNormAmount()) > 0) {
//                    throw new RemoteServiceException("外购辅材师傅分账金额不能大于收费标准");
//                }
//                outWorkerAmount = bean.getOutWorkerAmount();
//                outWebsitAmount = bean.getNormAmount().subtract(outWorkerAmount);
//            } else {
//                outWebsitAmount = bean.getNormAmount();
//            }
            bean.setSelfWorkerAmount(selWorkerAmount)
                    .setSelfWebsitAmount(selWebsitAmount)
//                    .setOutWorkerAmount(outWorkerAmount)
//                    .setOutWebsitAmount(outWebsitAmount)
            ;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void edit(WebsitNormChargeBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        WebsitNormCharge oldNormCharge = websitNormChargeService.getById(bean.getNormId());
        bean.setCompanyWechatId(oldNormCharge.getCompanyWechatId());
        bean.setCompanyWechatName(oldNormCharge.getCompanyWechatName());
        // 分账检查
        this.checkAmount(bean);
        // 库存单位不为空时,调用添加处理
        this.stockUnitEmptyAdd(bean);

        bean.updateById();

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            websitNormRelaService.lambdaUpdate()
                    .eq(WebsitNormRela::getCompanyWechatId, bean.getCompanyWechatId())
                    .eq(WebsitNormRela::getNormId, bean.getNormId())
                    .remove();
            for (WebsitNormRela item : bean.getItems()) {
                item.setCompanyWechatId(bean.getCompanyWechatId())
                        .setNormId(bean.getNormId());
            }
            websitNormRelaService.saveBatch(bean.getItems());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateStatus(List<String> ids, StateEnum stateEnum) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (Objects.isNull(stateEnum)) {
            throw new RemoteServiceException("状态不能为空");
        }
        websitNormChargeService.lambdaUpdate()
                .set(WebsitNormCharge::getStatus, stateEnum.getKey())
                .set(WebsitNormCharge::getUpdateBy, adminUser.getJoinNickName())
                .set(WebsitNormCharge::getUpdateTime, DateUtil.date())
                .eq(WebsitNormCharge::getCompanyWechatId, adminUser.getAdminCompanyWechat().getCompanyWechatId())
                .in(WebsitNormCharge::getNormId, ids)
                .update();
    }

    public Object importData(MultipartFile file) throws IOException {

        AdminUserCom adminUser = commonLogic.getAdminUser();

        String companyWechatId = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyWechatId() : null;
        String companyName = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyName() : null;

        List<Object> objects = ExcelUtils.importExcel(file);
        List<WebsitNormCharge> goodsList = new ArrayList<>();

        List<MaterialCategoryTree> categoryTrees = materialCategoryLogic.materialCategoryTree(null);

        Map<String, MaterialCategoryTree> treeMap = categoryTrees.stream()
                .collect(Collectors.toMap(MaterialCategoryTree::getCategoryName, Function.identity()));

        List<String> unitList = sysDictCompanyService.lambdaQuery()
                .eq(SysDictCompany::getDictType, "ASSIST_UNIT")
                .list()
                .stream()
                .map(SysDictCompany::getDictValue)
                .collect(Collectors.toList());

        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            if (row.size() < 6) {
                row.add(null);
                row.add(null);
                row.add(null);
            }
            if (row.size() < 7) {
                row.add(null);
                row.add(null);
            }
            if (row.size() < 8) {
                row.add(null);
            }
            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 大类不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类不能为空");
            }
            if (Objects.isNull(row.get(2))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称不能为空");
            }
            if (Objects.isNull(row.get(3))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 单位不能为空");
            }
            if (Objects.isNull(row.get(4))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 收费标准不能为空");
            }
            if (Objects.isNull(row.get(5))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 自有库存师傅分账金额不能为空");
            }
//            if (Objects.isNull(row.get(6))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 外购辅材师傅分账金额不能为空");
//            }
            if (Objects.isNull(row.get(6))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 师傅手工费用不能为空");
            }

            String parentCategoryStr = (String) row.get(0);
            String categoryStr = (String) row.get(1);
            String goodsNameStr = (String) row.get(2);
            String unitStr = (String) row.get(3);
            String salesStr = (String) row.get(4);
//            String amount1Str = (String) row.get(5);
//            String amount2Str = (String) row.get(6);
//            String manualAmountStr = (String) row.get(6);
            String goodsCodeStr = (String) row.get(5);
            String specificationStr = (String) row.get(6);
            String remark = (String) row.get(7);

            if (!treeMap.containsKey(parentCategoryStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 大类信息不存在");
            }
            MaterialCategoryTree categoryTree = treeMap.get(parentCategoryStr);
            if (CollectionUtil.isEmpty(categoryTree.getChild())) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类信息不存在");
            }
            Map<String, MaterialCategoryTree> childMap = categoryTree.getChild()
                    .stream()
                    .collect(Collectors.toMap(MaterialCategoryTree::getCategoryName, Function.identity()));
            if (!childMap.containsKey(categoryStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类信息不存在");
            }
            MaterialCategoryTree child = childMap.get(categoryStr);

            Integer count = websitNormChargeService.lambdaQuery()
                    .eq(WebsitNormCharge::getCompanyWechatId, companyWechatId)
                    .eq(WebsitNormCharge::getNormType, NormTypeEnum.M.getKey())
                    .eq(WebsitNormCharge::getNormName, goodsNameStr)
                    .count();

            if (count > 0) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称重复");
            }

            if (!unitList.contains(unitStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 单位信息不存在");
            }

            WebsitNormCharge goods = new WebsitNormCharge();

            goods.setCompanyWechatId(companyWechatId);
            goods.setCompanyWechatName(companyName);
            goods.setNormName(goodsNameStr);
            goods.setNormCode(goodsCodeStr);
            goods.setParentCategoryId(categoryTree.getCategoryId());
            goods.setCategoryId(child.getCategoryId());
            goods.setSpecification(specificationStr);
            goods.setRemark(remark);
            goods.setNormAmount(new BigDecimal(salesStr));
            goods.setSelfWorkerAmount(goods.getNormAmount());
//            goods.setSelfWorkerAmount(new BigDecimal(amount1Str));
//            goods.setSelfWebsitAmount(goods.getNormAmount().subtract(new BigDecimal(amount1Str)));
//            goods.setOutWorkerAmount(new BigDecimal(amount2Str));
//            goods.setOutWebsitAmount(goods.getNormAmount().subtract(new BigDecimal(amount2Str)));
//            goods.setManualAmount(new BigDecimal(manualAmountStr));
            goods.setUnit(unitStr);
            goods.setNormType(NormTypeEnum.M.getKey());

            if (goods.getSelfWorkerAmount().compareTo(goods.getNormAmount()) > 0) {
                throw new RemoteServiceException("第" + (i+1) + "行, 自有库存师傅分账金额不能大于收费标准");
            }

//            if (goods.getOutWorkerAmount().compareTo(goods.getNormAmount()) > 0) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 外购辅材师傅分账金额不能大于收费标准");
//            }

            goodsList.add(goods);
        }

        if (CollectionUtil.isNotEmpty(goodsList)) {
            websitNormChargeService.saveBatch(goodsList);
        }

        return null;
    }

    public Object importData2(MultipartFile file) throws IOException {

        AdminUserCom adminUser = commonLogic.getAdminUser();

        String companyWechatId = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyWechatId() : null;
        String companyName = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyName() : null;

        List<Object> objects = ExcelUtils.importExcel(file);
        List<WebsitNormCharge> goodsList = new ArrayList<>();

        List<MaterialCategoryTree> categoryTrees = materialCategoryLogic.materialCategoryTree(null);

        Map<String, MaterialCategoryTree> treeMap = categoryTrees.stream()
                .collect(Collectors.toMap(MaterialCategoryTree::getCategoryName, Function.identity()));

        List<String> unitList = sysDictCompanyService.lambdaQuery()
                .eq(SysDictCompany::getDictType, "ASSIST_UNIT")
                .list()
                .stream()
                .map(SysDictCompany::getDictValue)
                .collect(Collectors.toList());

        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            if (row.size() < 6) {
                row.add(null);
                row.add(null);
                row.add(null);
            }
            if (row.size() < 7) {
                row.add(null);
                row.add(null);
            }
            if (row.size() < 8) {
                row.add(null);
            }
            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 大类不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类不能为空");
            }
            if (Objects.isNull(row.get(2))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称不能为空");
            }
            if (Objects.isNull(row.get(3))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 单位不能为空");
            }
            if (Objects.isNull(row.get(4))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 收费标准不能为空");
            }
//            if (Objects.isNull(row.get(5))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 师傅分账金额不能为空");
//            }
//            if (Objects.isNull(row.get(6))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 师傅手工费用不能为空");
//            }

            String parentCategoryStr = (String) row.get(0);
            String categoryStr = (String) row.get(1);
            String goodsNameStr = (String) row.get(2);
            String unitStr = (String) row.get(3);
            String salesStr = (String) row.get(4);
//            String amount1Str = (String) row.get(5);
//            String manualAmountStr = (String) row.get(6);
            String goodsCodeStr = (String) row.get(5);
            String specificationStr = (String) row.get(6);
            String remark = (String) row.get(7);

            if (!treeMap.containsKey(parentCategoryStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 大类信息不存在");
            }
            MaterialCategoryTree categoryTree = treeMap.get(parentCategoryStr);
            if (CollectionUtil.isEmpty(categoryTree.getChild())) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类信息不存在");
            }
            Map<String, MaterialCategoryTree> childMap = categoryTree.getChild()
                    .stream()
                    .collect(Collectors.toMap(MaterialCategoryTree::getCategoryName, Function.identity()));
            if (!childMap.containsKey(categoryStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 小类信息不存在");
            }
            MaterialCategoryTree child = childMap.get(categoryStr);

            Integer count = websitNormChargeService.lambdaQuery()
                    .eq(WebsitNormCharge::getCompanyWechatId, companyWechatId)
                    .eq(WebsitNormCharge::getNormType, NormTypeEnum.S.getKey())
                    .eq(WebsitNormCharge::getNormName, goodsNameStr)
                    .count();

            if (count > 0) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称重复");
            }

            if (!unitList.contains(unitStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 单位信息不存在");
            }

            WebsitNormCharge goods = new WebsitNormCharge();

            goods.setCompanyWechatId(companyWechatId);
            goods.setCompanyWechatName(companyName);
            goods.setNormName(goodsNameStr);
            goods.setNormCode(goodsCodeStr);
            goods.setParentCategoryId(categoryTree.getCategoryId());
            goods.setCategoryId(child.getCategoryId());
            goods.setSpecification(specificationStr);
            goods.setRemark(remark);
            goods.setNormAmount(new BigDecimal(salesStr));
            goods.setSelfWorkerAmount(goods.getNormAmount());
//            goods.setSelfWorkerAmount(new BigDecimal(amount1Str));
//            goods.setSelfWebsitAmount(goods.getNormAmount().subtract(new BigDecimal(amount1Str)));
//            goods.setManualAmount(new BigDecimal(manualAmountStr));
            goods.setUnit(unitStr);
            goods.setNormType(NormTypeEnum.S.getKey());

            if (goods.getSelfWorkerAmount().compareTo(goods.getNormAmount()) > 0) {
                throw new RemoteServiceException("第" + (i+1) + "行, 师傅分账金额不能大于收费标准");
            }

            goodsList.add(goods);
        }

        if (CollectionUtil.isNotEmpty(goodsList)) {
            websitNormChargeService.saveBatch(goodsList);
        }

        return null;
    }
}
