package com.zfire.mall.manager.logic.k3;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.admin.AdminUserVisitAccBean;
import com.zfire.mall.manager.bean.k3.RequestApiBean;
import com.zfire.mall.manager.bean.k3.StockPosition;
import com.zfire.mall.manager.bean.k3.StockPositionStock;
import com.zfire.mall.manager.bean.k3.StockPositionStockVO;
import com.zfire.mall.manager.bean.listV2.StockTollVO;
import com.zfire.mall.manager.bean.supplier.KingDeeStockVO;
import com.zfire.mall.manager.commonmapper.StockK3Mapper;
import com.zfire.mall.manager.constant.KingDeeCons;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.retail.RetailOrderLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class K3StockLogic {

    @Resource
    KingDeeStockService kingDeeStockService;
    @Resource
    K3Logic k3Logic;

    @Autowired
    StockReserveService stockReserveService;

    @Autowired
    StockTollService stockTollService;

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    StockCorrespondService stockCorrespondService;

    @Autowired
    StockK3Mapper stockK3Mapper;

    @Autowired
    InvoiceApplicationService invoiceApplicationService;

    @Autowired
    StockCorrespondPositionService stockCorrespondPositionService;

    @Autowired
    RetailOrderService retailOrderService;
    @Autowired
    RetailOrderItemService retailOrderItemService;
    @Autowired
    EnginOrderService enginOrderService;
    @Autowired
    EnginOrderItemService enginOrderItemService;
    @Autowired
    AdminUserStockService adminUserStockService;

    @Autowired
    KingDeeCategoryService kingDeeCategoryService;

    @Autowired
    StockCorrespondCategoryService stockCorrespondCategoryService;

    @Autowired
    StockForceCategoryService stockForceCategoryService;

    @Autowired
    AdminWebsitService adminWebsitService;

//    public void allSync(String orgId, String orgNumber, String startTime, String endTime) throws Exception {
//        // 调用仓库接口
//        RequestApiBean request = k3Logic.getInstance(orgId, orgNumber, KingDeeCons.STOCK_INFO, startTime, endTime);
//        String filterStr = "FDocumentStatus = 'C' AND FUseOrgId.FNUMBER = %s "+ k3Logic.supplySql("FAuditDate", startTime, endTime);
//        request.setFieldKeys("FStockId,FNUMBER,FNAME,FUseOrgId.FNUMBER,FUseOrgId.FName,FPrincipal.FName,FStockProperty,FThirdStockType,FDocumentStatus,FAllowMinusQty,FIsOpenLocation,FNotExpQty,FAvailableAlert," +
//                "FCreateOrgId.FName,FSupplierId.FName,FCustomerId.FName,FAddress,FTel,FDescription,FGroup.FName,FIsGYStock,FGYStockNumber,FTHIRDSTOCKNO,FStockStatusType," +
//                "FDefStockStatusId.FName,FDefReceiveStatusId.FName,FAllowMRPPlan,FAllowLock,FAvailablePicking,FSortingPriority,FLocListFormatter");
//        request.setFilterString(String.format(filterStr, orgNumber));
//        request.setOrderString("FStockId ASC");
//
//        String[] fields = new String[]{"id","number","name","useOrgNumber","useOrgName","principalName","stockProperty","thirdStockType","documentStatus","allowMinusQty","openLocation","notExpQty","availableAlert",
//        "createOrgName","supplierName","customerName","address","tel","description","groupName","gysStock","gysStockNumber","thirdStockNo","stockStatusType",
//        "defStockStatusName","defReceiveStatusName","allowMrpPlan","allowLock","availablePicking","sortingPriority","loclistFormatter"};
//        List<KingDeeStock> objects = k3Logic.allSync(request, fields, KingDeeStock.class);
//        if (!CollectionUtils.isEmpty(objects)) {
//            kingDeeStockService.saveOrUpdateBatch(objects);
//        }
//    }

    public IPage<StockReserve> listReserve(Integer pageNum, Integer pageSize) {
        return stockReserveService.lambdaQuery().orderByDesc(StockReserve::getCreateTime).page(new Page<>(pageNum,pageSize));
    }


    public void addReserve(StockReserve stockReserver) {

        stockReserver.insert();
    }

    public void updateReserve(StockReserve stockReserver) {
        stockReserver.updateById();
        commonLogic.saveLog(stockReserver.getId());
    }

    public IPage<StockToll> listToll(BigDecimal freeDay, BigDecimal toll, String customerName, Integer pageNum, Integer pageSize) {
        return stockTollService.lambdaQuery()
                .eq(!StringUtils.isEmpty(freeDay),StockToll::getFreeDay,freeDay)
                .eq(toll!=null,StockToll::getToll,toll)
                .like(!StringUtils.isEmpty(customerName),StockToll::getCustomerName,customerName)
                .orderByDesc(StockToll::getCreateTime)
                .page(new Page<>(pageNum,pageSize));
    }

    public void addToll(StockToll stockToll, HttpServletRequest request) {
        if (stockTollService.lambdaQuery().eq(StockToll::getCustomerNumber,stockToll.getCustomerNumber()).count() > 0)
            throw new RemoteServiceException("当前经销商已有规则");
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        stockToll.insert();
    }

    public void updateToll(StockToll stockToll, HttpServletRequest request) {
        if (stockTollService.lambdaQuery().eq(StockToll::getCustomerNumber,stockToll.getCustomerNumber()).ne(StockToll::getId,stockToll.getId()).count() > 0)
            throw new RemoteServiceException("当前经销商已有规则");
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        stockToll.updateById();

        commonLogic.saveLog(stockToll.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    public void addStock(StockPosition stockPosition, HttpServletRequest request) {
        if (stockCorrespondService.lambdaQuery().eq(StockCorrespond::getName,stockPosition.getName()).count() > 0)
            throw new RemoteServiceException("当前仓库已有对应关系");
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        stockPosition.insert();

        List<StockCorrespondPosition> stockCorrespondPositions = new ArrayList<>();
        for (String stockId : stockPosition.getStockIds()) {
            StockCorrespondPosition stockCorrespondPosition = new StockCorrespondPosition();
            stockCorrespondPosition.setStockId(stockId);
            stockCorrespondPosition.setCorrespondId(stockPosition.getId());
            stockCorrespondPositions.add(stockCorrespondPosition);
        }
        stockCorrespondPositionService.saveBatch(stockCorrespondPositions);

        this.addCategorys(stockPosition);
    }

    public IPage<StockPositionStock> listStock(String name, String stockName, Integer pageNum, Integer pageSize) {
        return stockK3Mapper.listStock(new Page<>(pageNum,pageSize),name, stockName,null);
    }

    public StockPositionStock detailStock(String id) {
        if (CollectionUtils.isEmpty(stockK3Mapper.listStock(new Page<>(1, 1), null, null, id).getRecords()))
            throw new RemoteServiceException("无该id");
        StockPositionStock stockPositionStock = stockK3Mapper.listStock(new Page<>(1, 1), null, null, id).getRecords().get(0);

        List<StockCorrespondCategory> list = stockCorrespondCategoryService.lambdaQuery().eq(StockCorrespondCategory::getCorrespondId, id).list();
        if (!CollectionUtils.isEmpty(list)) {
        List<String> collect = list.stream().map(StockCorrespondCategory::getCategoryId).collect(Collectors.toList());

            List<KingDeeCategory> kingDeeCategories = kingDeeCategoryService.lambdaQuery().in(KingDeeCategory::getId, collect).list();
            stockPositionStock.setKingDeeCategories(kingDeeCategories);
        }

        List<StockForceCategory> stockForceCategories = stockForceCategoryService.lambdaQuery().eq(StockForceCategory::getCorrespondId, id).list();

        if (!CollectionUtils.isEmpty(stockForceCategories)) {
            stockPositionStock.setStockForceCategories(stockForceCategories);
        }

        return stockPositionStock;
    }

    public StockToll detailToll(String id) {
        return stockTollService.getById(id);
    }

    public void importToll(InputStream inputStream, HttpServletRequest request) {
        //读取excel数据
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        reader.addHeaderAlias("经销商编码", "customerNumber");
        reader.addHeaderAlias("经销商名称", "customerName");
        reader.addHeaderAlias("免费天数", "freeDay");
        reader.addHeaderAlias("每立方收费（元）", "toll");

        List<StockToll> stockToll = reader.readAll(StockToll.class);

        stockTollService.saveBatch(stockToll);
    }

    public ExcelData exportToll(List<StockToll> records) {
        String[] titles = new String[]{"经销商编码", "经销商名称", "存放免费天数", "收费规则（每立方米）", "创建人", "创建时间","更新人","更新时间"};
        List<List<Object>> rows = new ArrayList<>();
        for (StockToll adminUser : records) {
            List<Object> row = new ArrayList<>();
            row.add(adminUser.getCustomerNumber());
            row.add(adminUser.getCustomerName());
            row.add(adminUser.getFreeDay());
            row.add(adminUser.getToll());
            row.add(adminUser.getCreateBy());
            row.add(DateUtil.formatDate(adminUser.getCreateTime()));
            row.add(adminUser.getUpdateBy());
            row.add(DateUtil.formatDate(adminUser.getUpdateTime()));
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        excelData.setName("sheet1");
        return excelData;
    }

    public IPage<KingDeeStock> list(String name,Integer Inquire,Integer stockType, Integer pageNum, Integer pageSize) {
        return kingDeeStockService.lambdaQuery()
                .eq(!StringUtils.isEmpty(name),KingDeeStock::getName,name)
                .eq(stockType != null,KingDeeStock::getStockType,stockType)
                .eq(Inquire != null,KingDeeStock::getInquire,Inquire)
                .orderByDesc(KingDeeStock::getCreateTime)
                .page(new Page<>(pageNum,pageSize));
    }

    public KingDeeStock detail(String id) {
        return kingDeeStockService.getById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteStock(List<String> id) {
        for (String s : id) {
            if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getCorrespondId,s).count()>0) {
                throw new RemoteServiceException("当前仓库已有申请发货单，无法修改里面的仓库");
            }
        }
        stockCorrespondService.removeByIds(id);
        stockCorrespondPositionService.lambdaUpdate().in(StockCorrespondPosition::getCorrespondId,id).remove();
        stockCorrespondCategoryService.lambdaUpdate().in(StockCorrespondCategory::getCorrespondId,id).remove();
        stockForceCategoryService.lambdaUpdate().in(StockForceCategory::getCorrespondId,id).remove();
    }

    public void deleteToll(String id) {
        stockTollService.removeById(id);
    }

    @Transactional
    public void updateStock(StockPosition stockPosition, HttpServletRequest request) {
        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getCorrespondId,stockPosition.getId()).count()>0) {

            this.addCategorys(stockPosition);

            return;
        }

        if (stockCorrespondService.lambdaQuery().eq(StockCorrespond::getName,stockPosition.getName()).ne(StockCorrespond::getId,stockPosition.getId()).count() > 0)
            throw new RemoteServiceException("当前仓库已有对应关系");
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        stockPosition.updateById();

        this.addCategorys(stockPosition);

    }

    public void addCategorys(StockPosition stockPosition) {
        stockCorrespondPositionService.lambdaUpdate().eq(StockCorrespondPosition::getCorrespondId,stockPosition.getId()).remove();
        List<StockCorrespondPosition> stockCorrespondPositions = new ArrayList<>();
        for (String stockId : stockPosition.getStockIds()) {
            StockCorrespondPosition stockCorrespondPosition = new StockCorrespondPosition();
            stockCorrespondPosition.setStockId(stockId);
            stockCorrespondPosition.setCorrespondId(stockPosition.getId());
            stockCorrespondPositions.add(stockCorrespondPosition);
        }
        stockCorrespondPositionService.saveBatch(stockCorrespondPositions);

        stockCorrespondCategoryService.lambdaUpdate().eq(StockCorrespondCategory::getCorrespondId,stockPosition.getId()).remove();

        List<StockCorrespondCategory> stockCorrespondCategories = new ArrayList<>();
        for (String category : stockPosition.getCategoryIds()) {
            StockCorrespondCategory stockCorrespondCategory = new StockCorrespondCategory();
            stockCorrespondCategory.setCorrespondId(stockPosition.getId());
            stockCorrespondCategory.setCategoryId(category);
            stockCorrespondCategories.add(stockCorrespondCategory);
        }
        stockCorrespondCategoryService.saveBatch(stockCorrespondCategories);


/*        stockForceCategoryService.lambdaUpdate().eq(StockForceCategory::getCorrespondId,stockPosition.getId()).remove();
        List<StockForceCategory> stockForceCategories = new ArrayList<>();
        for (String stockId : stockPosition.getQiangzhiCategoryIds()) {
            StockForceCategory stockForceCategory = new StockForceCategory();
            stockForceCategory.setCategoryId(stockId);
            stockForceCategory.setCorrespondId(stockPosition.getId());
            stockForceCategory.setCorrespondName(stockPosition.getName());
            stockForceCategories.add(stockForceCategory);
        }
        stockForceCategoryService.saveBatch(stockForceCategories);*/
    }


    public List<KingDeeStock> listPosition(String correspondId, Integer inquire) {
        return stockK3Mapper.listPosition(correspondId,inquire);
    }

    public void update(String id, Integer inquire, Integer stockType) {
        KingDeeStock kingDeeStock = new KingDeeStock();
        kingDeeStock.setId(id);
        kingDeeStock.setInquire(inquire);
        kingDeeStock.setStockType(stockType);
        kingDeeStock.updateById();
    }


    /**
     * 库存到货访问通知-列表
     */
    public IPage<AdminUserVisitAccBean> visitAccList(String specification,Integer pageNum,Integer pageSize,HttpServletRequest request){
        AdminUserCom adminUser = commonLogic.getAdminUser();
//        Date date = DateUtil.parseDate("2000-01-01 00:00:00");
//        if(adminUser.getVisitAccTime() != null){
//            date = adminUser.getVisitAccTime();
//        }

        Date date = DateUtil.offsetDay(new Date(),-3);

        List<String> materialIds = new ArrayList<>();
        if(adminUser.getIsCustomer()){
            //要过滤的物料
            List<RetailOrder> retailOrders = retailOrderService.lambdaQuery()
                    .in(RetailOrder::getCustomerId, adminUser.getCustomerId())
                    .eq(RetailOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                    .list();
            List<EnginOrder> enginOrders = enginOrderService.lambdaQuery()
                    .in(EnginOrder::getCustomerId, adminUser.getCustomerId())
                    .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                    .list();
            List<String> retailOrderIds = retailOrders.stream().map(RetailOrder::getId).distinct().collect(Collectors.toList());
            List<String> enginOrderIds = enginOrders.stream().map(EnginOrder::getEnginOrderId).collect(Collectors.toList());

            if(retailOrderIds.size() > 0) {
                List<RetailOrderItem> list = retailOrderItemService.lambdaQuery().select(RetailOrderItem::getMaterialId)
                        .in(RetailOrderItem::getRetailOrderId, retailOrderIds)
                        .like(!StringUtils.isEmpty(specification),RetailOrderItem::getSpecification,specification)
                        .gt(RetailOrderItem::getRefundableQty,0)
                        .list();
                List<String> materialIds1 = list.stream().map(RetailOrderItem::getMaterialId).distinct().collect(Collectors.toList());
                materialIds.addAll(materialIds1);
            }

            if(enginOrderIds.size() > 0) {
                List<EnginOrderItem> list1 = enginOrderItemService.lambdaQuery()
                        .select(EnginOrderItem::getMaterialId)
                        .in(EnginOrderItem::getParentId, enginOrderIds)
                        .like(!StringUtils.isEmpty(specification),EnginOrderItem::getSpecification,specification)
                        .gt(EnginOrderItem::getRefundableQty,0)
                        .list();
                List<String> materialIds2 = list1.stream().map(EnginOrderItem::getMaterialId).distinct().collect(Collectors.toList());
                materialIds.addAll(materialIds2);
            }
        }

        //要过滤的仓库
        List<AdminUserStock> adminUserStocks = adminUserStockService.lambdaQuery().eq(AdminUserStock::getAdminUserId, adminUser.getAdminUserId()).list();
        List<String> correspondIds = adminUserStocks.stream().map(AdminUserStock::getCorrespondId).collect(Collectors.toList());


        IPage<AdminUserVisitAccBean> page = stockK3Mapper
                .visitAccList(new Page(pageNum, pageSize),specification, DateUtil.formatDateTime(date),materialIds,correspondIds);
        adminUser.setVisitAccTime(new Date());
        adminUser.updateById();

        //commonLogic.reloadAdminUserBean(adminUser,request);
        return page;
    }


    /**
     * 库存到货访问通知-数量
     */
    public Integer visitAccCount(){
        AdminUserCom adminUser = commonLogic.getAdminUser();
        Date date = DateUtil.parseDate("2000-01-01 00:00:00");
        if(adminUser.getVisitAccTime() != null){
            date = adminUser.getVisitAccTime();
        }
        Integer total = stockK3Mapper.visitAccCount(DateUtil.formatDate(date));
        return total;
    }


    public IPage<KingDeeStockVO> listV2(ZfireParamBean zfireParamBean) {
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return stockK3Mapper.listV2(new Page(zfireParamBean.getPageNum(),zfireParamBean.getPageSize()),zfireParamBean);
    }

    public IPage<StockPositionStockVO> listStockV2(ZfireParamBean zfireParamBean) {
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return stockK3Mapper.listStockV2(new Page(zfireParamBean.getPageNum(),zfireParamBean.getPageSize()),zfireParamBean);
    }

    public IPage<StockTollVO> listTollV2(ZfireParamBean zfireParamBean) {
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        return stockK3Mapper.listTollV2(new Page(zfireParamBean.getPageNum(),zfireParamBean.getPageSize()),zfireParamBean);
    }
}
