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

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.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.material.manage.*;
import com.gree.mall.manager.commonmapper.MaterialMapper;
import com.gree.mall.manager.enums.admin.AdminWebsitTypeEnum;
import com.gree.mall.manager.enums.material.MaterialFlagEnum;
import com.gree.mall.manager.enums.material.WebsitGoodsTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.material.stock.WebitPurchaseStockLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
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.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 WebsitPurchaseLogic {

    private final CommonLogic commonLogic;
    private final MaterialMapper materialMapper;
    private final WebsitPurchaseService websitPurchaseService;
    private final WebsitPurchaseItemService websitPurchaseItemService;
    private final WebitPurchaseStockLogic webitPurchaseStockLogic;
    private final WebsitGoodsPriceService websitGoodsPriceService;
    private final AdminWebsitService adminWebsitService;
    private final WebsitVenderService websitVenderService;
    private final WebsitGoodsService websitGoodsService;
    private final WebsitStockService websitStockService;
    private final WebsitGoodsCategoryService websitGoodsCategoryService;

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

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

    public WebsitPurchaseBean detail(String purchaseId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitPurchaseBean bean = new WebsitPurchaseBean();
        WebsitPurchase purchase = websitPurchaseService.getById(purchaseId);
        BeanUtils.copyProperties(purchase, bean);
        bean.setImageUrl(purchase.getImageUrl());
        String companyId = Objects.isNull(adminUser.getAdminCompanyWechat()) ? null : adminUser.getAdminCompanyWechat().getCompanyWechatId();
        List<WebsitPurchaseItemBean> list = websitPurchaseItemService.lambdaQuery()
                .eq(StringUtils.isNotBlank(companyId), WebsitPurchaseItem::getCompanyWechatId, companyId)
                .eq(WebsitPurchaseItem::getPurchaseId, purchaseId)
                .list()
                .stream()
                .map(v -> {
                    WebsitPurchaseItemBean item = new WebsitPurchaseItemBean();
                    BeanUtils.copyProperties(v, item);
                    return item;
                }).collect(Collectors.toList());
        bean.setItems(list);

        // 当前库存数量
//        if (bean.getFlag().equals(MaterialFlagEnum.SAVE.getKey())) {
            List<WebsitStock> stocks = websitStockService.lambdaQuery()
                    .in(WebsitStock::getGoodsId, list.stream().map(WebsitPurchaseItemBean::getGoodsId).collect(Collectors.toList()))
                    .eq(WebsitStock::getCompanyWechatId, bean.getCompanyWechatId())
                    .eq(WebsitStock::getStorageId, purchase.getStorageId())
                    .eq(WebsitStock::getWebsitId, bean.getWebsitId())
                    .list();
            if (CollectionUtil.isNotEmpty(stocks)) {
                Map<String, BigDecimal> stockMap = stocks.stream().collect(Collectors.toMap(WebsitStock::getGoodsId, WebsitStock::getQty));
                for (WebsitPurchaseItemBean itemBean : list) {
                    itemBean.setStockQty(stockMap.getOrDefault(itemBean.getGoodsId(), BigDecimal.ZERO));
                }
//            }
        }
        return bean;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(WebsitPurchaseBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (Objects.isNull(adminUser.getAdminCompanyWechat())) {
            throw new RemoteServiceException("平台账号禁用操作");
        }

        bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());

        // 根据配置是否注入仓位
        final Storage storage = webitPurchaseStockLogic.handleStorage(adminUser, bean.getWebsitId(), bean.getGoodsType(), bean.getStorageId());
        bean.setStorageId(storage.getStorageId());
        bean.setStorageName(storage.getStorageName());

        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
        WebsitPurchase purchase = new WebsitPurchase();
        BeanUtils.copyProperties(bean, purchase);
        purchase.setPurchaseId(IdWorker.getIdStr());
        purchase.setPurchaseTime(DateUtil.date());
        purchase.setImageUrl(bean.getImageUrl());

        BigDecimal totalAmount = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            List<WebsitPurchaseItem> itemList = new ArrayList<>();
            for (WebsitPurchaseItemBean itemBean : bean.getItems()) {
                WebsitPurchaseItem item = new WebsitPurchaseItem();
                BeanUtils.copyProperties(itemBean, item);
//                if (purchase.getGoodsType().equals(WebsitGoodsTypeEnum.P.getKey())) {
//                    item.setCost(BigDecimal.ZERO);
//                }

                item.setCompanyWechatId(purchase.getCompanyWechatId())
                        .setPurchaseId(purchase.getPurchaseId())
                        .setWebsitId(purchase.getWebsitId())
                        .setWebsitName(purchase.getWebsitName())
                        .setGoodsType(purchase.getGoodsType())
                        .setCostValue(item.getCost().multiply(item.getRecQty()));
                itemList.add(item);
                totalAmount = totalAmount.add(item.getCostValue());
            }
            websitPurchaseItemService.saveBatch(itemList);
        }

        purchase.setTotalAmount(totalAmount);
        purchase.insert();
    }

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

        if (Objects.isNull(adminUser.getAdminCompanyWechat())) {
            throw new RemoteServiceException("平台账号禁用操作");
        }

        WebsitPurchase purchase = websitPurchaseService.getById(bean.getPurchaseId());
        if (!purchase.getFlag().equals(MaterialFlagEnum.SAVE.getKey())) {
            throw new RemoteServiceException("采购入库非\"保存\"状态，不能再编辑");
        }

        bean.setCompanyWechatId(purchase.getCompanyWechatId());
        bean.setCompanyWechatName(purchase.getCompanyWechatName());

        // 根据配置是否注入仓位
        final Storage storage = webitPurchaseStockLogic.handleStorage(adminUser, bean.getWebsitId(), purchase.getGoodsType(), bean.getStorageId());
        bean.setStorageId(storage.getStorageId());
        bean.setStorageName(storage.getStorageName());

        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
        purchase = new WebsitPurchase();
        BeanUtils.copyProperties(bean, purchase);
        purchase.setGoodsType(purchase.getGoodsType());
        purchase.setPurchaseTime(purchase.getPurchaseTime());
        purchase.setImageUrl(bean.getImageUrl());

        BigDecimal totalAmount = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            websitPurchaseItemService.lambdaUpdate()
                    .eq(WebsitPurchaseItem::getCompanyWechatId, bean.getCompanyWechatId())
                    .eq(WebsitPurchaseItem::getPurchaseId, bean.getPurchaseId())
                    .remove();
            List<WebsitPurchaseItem> itemList = new ArrayList<>();
            for (WebsitPurchaseItemBean itemBean : bean.getItems()) {
                WebsitPurchaseItem item = new WebsitPurchaseItem();
                BeanUtils.copyProperties(itemBean, item);
//                if (purchase.getGoodsType().equals(WebsitGoodsTypeEnum.P.getKey())) {
//                    item.setCost(BigDecimal.ZERO);
//                }
                item.setCompanyWechatId(purchase.getCompanyWechatId())
                        .setPurchaseId(purchase.getPurchaseId())
                        .setWebsitId(purchase.getWebsitId())
                        .setWebsitName(purchase.getWebsitName())
                        .setGoodsType(purchase.getGoodsType())
                        .setCostValue(item.getCost().multiply(item.getRecQty()));
                itemList.add(item);

                totalAmount = totalAmount.add(item.getCostValue());
            }
            websitPurchaseItemService.saveBatch(itemList);
        }

        purchase.setTotalAmount(totalAmount);
        purchase.updateById();
    }

    @Transactional(rollbackFor = Exception.class)
    public void confirm(String purchaseId, MaterialFlagEnum flag, String storageId) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitPurchase purchase = websitPurchaseService.getById(purchaseId);
        if (Objects.isNull(adminUser.getAdminCompanyWechat())) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        if (!purchase.getCompanyWechatId().equals(adminUser.getCompanyWechatId())) {
            throw new RuntimeException("关键信息错误");
        }

        if (purchase.getIsImport() && StringUtils.isBlank(storageId)) {
            throw new RemoteServiceException("请选择仓库");
        }

//        if (purchase.getIsImport()) {
            final Storage storage = webitPurchaseStockLogic.handleStorage(adminUser, purchase.getWebsitId(), purchase.getGoodsType(), storageId);
            purchase.setStorageId(storageId)
                    .setStorageName(storage.getStorageName());
//        }

        purchase.setConfirmBy(adminUser.getNickName())
                .setConfirmTime(DateUtil.date());

        websitPurchaseService.lambdaUpdate()
                .set(WebsitPurchase::getFlag, flag.getKey())
                .set(WebsitPurchase::getConfirmBy, purchase.getConfirmBy())
                .set(WebsitPurchase::getConfirmTime, purchase.getConfirmTime())
                .set(WebsitPurchase::getStorageId, purchase.getStorageId())
                .set(WebsitPurchase::getStorageName, purchase.getStorageName())
                .eq(WebsitPurchase::getPurchaseId, purchaseId)
                .update();

        // 审核通过增加库存
        if (flag.getKey().equals(MaterialFlagEnum.OK.getKey())) {
            List<WebsitPurchaseItem> purchaseItems = websitPurchaseItemService.lambdaQuery()
                    .eq(WebsitPurchaseItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                    .eq(WebsitPurchaseItem::getPurchaseId, purchaseId)
                    .list();

            webitPurchaseStockLogic.newInStock(purchase, purchaseItems, "采购入库");

            // 没有入库过的辅材增加售价为0记录
            if (purchase.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey())) {
                List<WebsitGoods> goodsList = websitGoodsService.lambdaQuery()
                        .eq(WebsitGoods::getCompanyWechatId, purchase.getCompanyWechatId())
                        .in(WebsitGoods::getGoodsId, purchaseItems.stream()
                                .map(WebsitPurchaseItem::getGoodsId)
                                .collect(Collectors.toList()))
                        .list();

                List<WebsitGoodsPrice> priceList = websitGoodsPriceService.lambdaQuery()
                        .eq(WebsitGoodsPrice::getCompanyWechatId, purchase.getCompanyWechatId())
                        .eq(WebsitGoodsPrice::getWebsitId, purchase.getWebsitId())
                        .in(WebsitGoodsPrice::getGoodsId, purchaseItems.stream()
                                .map(WebsitPurchaseItem::getGoodsId)
                                .collect(Collectors.toList()))
                        .list();
                // 数量不相等
                if (priceList.size() != purchaseItems.size()) {
                    List<WebsitGoodsPrice> createPriceList = new ArrayList<>();

                    Map<String, WebsitGoodsPrice> goodsPriceMap = priceList.stream()
                            .collect(Collectors.toMap(WebsitGoodsPrice::getGoodsId, Function.identity(), (key1,key2) -> key2));

                    Map<String, BigDecimal> goodsMap = goodsList.stream()
                            .collect(Collectors.toMap(WebsitGoods::getGoodsId, WebsitGoods::getMarketPrice, (key1,key2) -> key2));

                    for (WebsitPurchaseItem item : purchaseItems) {
                        if (!goodsPriceMap.containsKey(item.getGoodsId())) {
                            WebsitGoodsPrice price = new WebsitGoodsPrice();
                            BigDecimal salesPrice = goodsMap.getOrDefault(item.getGoodsId(), BigDecimal.ZERO);
                            price.setCompanyWechatId(item.getCompanyWechatId());
                            price.setWebsitId(item.getWebsitId());
                            price.setWebsitName(item.getWebsitName());
                            price.setGoodsType(item.getGoodsType());
                            price.setGoodsId(item.getGoodsId());
                            price.setPrice(salesPrice);
                            price.setSheetId("");
                            price.setRemark(purchase.getRemark());

                            createPriceList.add(price);
                        }
                    }

                    if (CollectionUtil.isNotEmpty(createPriceList)) {
                        websitGoodsPriceService.saveBatch(createPriceList);
                    }
                }
            }
        }
    }

    public String importData(MultipartFile file, String type) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<Object> objects = ExcelUtils.importExcel(file);
        List<WebsitPurchaseItem> items = new ArrayList<>();

        List<AdminWebsit> adminWebsits;

        AdminWebsit adminWebsit = null;
        WebsitVender vender = null;
        BigDecimal totalAmount = BigDecimal.ZERO;

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

        if (adminUser.getType() == 0) {
            adminWebsits = adminWebsitService.lambdaQuery()
                    .eq(AdminWebsit::getWebsitId, adminUser.getAdminWebsitIds().get(0))
                    .list();
            adminWebsit = adminWebsits.get(0);
        } else if (adminUser.getType() == 1) {
            adminWebsits = adminWebsitService.lambdaQuery()
                    .eq(AdminWebsit::getType, AdminWebsitTypeEnum.C.getKey())
                    .in(AdminWebsit::getWebsitId, adminUser.getAdminWebsitIds())
                    .list();
        } else {
            throw new RemoteServiceException("平台账号不能导入");
        }

        if (CollectionUtil.isEmpty(adminWebsits)) {
            throw new RemoteServiceException("账号拥有网点信息为空");
        }

        Map<String, AdminWebsit> websitMap = adminWebsits.stream()
                .collect(Collectors.toMap(AdminWebsit::getName, Function.identity()));

        String purchaseId = IdWorker.getIdStr();

        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            if (row.size() < 4) {
                row.add(null);
                row.add(null);
                row.add(null);
            }
            if (row.size() < 5) {
                row.add(null);
                row.add(null);
            }
            if (row.size() < 6) {
                row.add(null);
            }
            if (i == 0) {
                if (Objects.isNull(row.get(4)) && adminUser.getType() == 1) {
                    throw new RemoteServiceException("网点名称不能为空");
                }
                if (Objects.isNull(row.get(0))) {
                    throw new RemoteServiceException("供应商不能为空");
                }
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("商品名称不能为空");
            }
            if (Objects.isNull(row.get(2))) {
                throw new RemoteServiceException("数量不能为空");
            }
            if (Objects.isNull(row.get(3))) {
                throw new RemoteServiceException("采购价格不能为空");
            }

            String venderStr = (String) row.get(0);
            String goodsStr = (String) row.get(1);
            String qtyStr = (String) row.get(2);
            String costStr;
            if (Objects.isNull(row.get(3))) {
                costStr = "0";
            } else {
                costStr = (String) row.get(3);
            }
            String websitStr;
            if (Objects.isNull(row.get(3))) {
                websitStr = "";
            } else {
                websitStr = (String) row.get(4);
            }
            String noteStr;
            if (Objects.isNull(row.get(5))) {
                noteStr = "";
            } else {
                noteStr = (String) row.get(5);
            }

            if (i == 0 && adminUser.getType() == 1) {
                adminWebsit = websitMap.get(websitStr);
                if (Objects.isNull(adminWebsit)) {
                    throw new RemoteServiceException("网点信息不存在");
                }

                vender = websitVenderService.lambdaQuery()
                        .eq(WebsitVender::getCompanyWechatId, companyWechatId)
                        .eq(WebsitVender::getVenderName, venderStr)
                        .last("limit 1")
                        .one();

                if (Objects.isNull(vender)) {
                    throw new RemoteServiceException("供应商信息不存在");
                }
            }

            final String replaceGoodsStr = goodsStr.replaceAll("'", "");

            WebsitGoods goods = websitGoodsService.lambdaQuery()
                    .eq(WebsitGoods::getCompanyWechatId, companyWechatId)
                    .eq(type.equals(WebsitGoodsTypeEnum.M.getKey()), WebsitGoods::getGoodsName, goodsStr)
                    .eq(type.equals(WebsitGoodsTypeEnum.P.getKey()), WebsitGoods::getGoodsCode, replaceGoodsStr)
                    .eq(WebsitGoods::getGoodsType, type)
                    .last("limit 1")
                    .one();

            if (Objects.isNull(goods)) {
                throw new RemoteServiceException("第" + (i+1) + "行，商品信息不存在");
            }

            WebsitGoodsCategory goodsCategory = websitGoodsCategoryService.lambdaQuery()
                    .eq(WebsitGoodsCategory::getCompanyWechatId, companyWechatId)
                    .eq(WebsitGoodsCategory::getCategoryId, goods.getGoodsCategoryId())
                    .one();

            BigDecimal qty = new BigDecimal(qtyStr);
            BigDecimal cost = new BigDecimal(costStr);

            WebsitPurchaseItem item = new WebsitPurchaseItem();
            item.setCompanyWechatId(companyWechatId);
            item.setWebsitId(adminWebsit.getWebsitId());
            item.setWebsitName(adminWebsit.getName());
            item.setPurchaseId(purchaseId);
            item.setGoodsType(type);
            item.setGoodsId(goods.getGoodsId());
            item.setGoodsName(goods.getGoodsName());
            item.setCost(cost);
            item.setCostValue(qty.multiply(cost));
            item.setRecQty(qty);
            item.setGoodsStockUnit(goods.getGoodsStockUnit());
            item.setGoodsSpecification(goods.getGoodsSpecification());
            item.setNote(noteStr);

            if (type.equals(WebsitGoodsTypeEnum.P.getKey())) {
                item.setBrand(goods.getBrandRelaName());
                item.setProductCategory(goods.getProductRelaName());
                item.setGoodsCode(goods.getGoodsCode());
//                List<WebsitGoodsBrandRela> brandRelas = websitGoodsBrandRelaService.lambdaQuery()
//                        .eq(WebsitGoodsBrandRela::getCompanyWechatId, item.getCompanyWechatId())
//                        .eq(WebsitGoodsBrandRela::getGoodsId, item.getGoodsId())
//                        .list();
//                if (CollectionUtil.isNotEmpty(brandRelas)) {
//                    String brand = brandRelas.stream().map(WebsitGoodsBrandRela::getBrandName).collect(Collectors.joining("/"));
//                    item.setBrand(brand);
//                }
//                List<WebsitGoodsCategoryRela> categoryRelas = websitGoodsCategoryRelaService.lambdaQuery()
//                        .eq(WebsitGoodsCategoryRela::getCompanyWechatId, item.getCompanyWechatId())
//                        .eq(WebsitGoodsCategoryRela::getGoodsId, item.getGoodsId())
//                        .list();
//                if (CollectionUtil.isNotEmpty(brandRelas)) {
//                    String category = categoryRelas.stream().map(WebsitGoodsCategoryRela::getCategoryName).collect(Collectors.joining("/"));
//                    item.setProductCategory(category);
//                }
            } else {
                item.setParentCategoryId(goods.getParentCategoryId());
                item.setParentCategoryName(goodsCategory.getParentCategoryName());
                item.setGoodsCategoryId(goods.getGoodsCategoryId());
                item.setGoodsCategoryName(goodsCategory.getCategoryName());
            }

            items.add(item);

            totalAmount = totalAmount.add(item.getCostValue());
        }

        if (CollectionUtil.isNotEmpty(items)) {
            // 合并重复商品
            Map<String, WebsitPurchaseItem> itemMap = items.stream()
                    .collect(Collectors.toMap(WebsitPurchaseItem::getGoodsId, Function.identity(), (key1, key2) -> key2));


            WebsitPurchase purchase = new WebsitPurchase();
            purchase.setPurchaseId(purchaseId);
            purchase.setCompanyWechatId(companyWechatId);
            purchase.setCompanyWechatName(companyName);
            purchase.setWebsitId(items.get(0).getWebsitId());
            purchase.setWebsitName(items.get(0).getWebsitName());
            purchase.setGoodsType(type);
            purchase.setVenderId(Objects.nonNull(vender) ? vender.getVenderId() : null);
            purchase.setVenderName(Objects.nonNull(vender) ? vender.getVenderName() : null);
            purchase.setPurchaseTime(DateUtil.date());
            purchase.setFlag(MaterialFlagEnum.SAVE.getKey());
            purchase.setTotalAmount(totalAmount);
            purchase.setIsImport(true);

            purchase.insert();
            websitPurchaseItemService.saveBatch(itemMap.values());
        }
        return "";
    }

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

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

    }
}
