package com.jwipc.contract.controller.pc;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.jwipc.contract.constant.ContractConst;
import com.jwipc.contract.constant.ModuleConst;
import com.jwipc.contract.dto.ContractDTO;
import com.jwipc.contract.dto.ContractDetailDTO;
import com.jwipc.contract.dto.ContractMroDTO;
import com.jwipc.contract.dto.ContractPrintDTO;
import com.jwipc.contract.logic.ContractLogic;
import com.jwipc.contract.logic.ContractSubSeqLogic;
import com.jwipc.inquiry.client.InquiryClient;
import com.jwipc.inquiry.dto.InquiryDetailByIdDTO;
import com.jwipc.inquiry.dto.InquiryDetailByIdDetailClientDTO;
import com.jwipc.log.annotation.AuditLogInter;
import com.jwipc.security.LoginUtil;
import com.jwipc.security.dto.CurrentUserDTO;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.supplier.client.TenderClient;
import com.jwipc.sys.client.*;
import com.jwipc.sys.client.dto.CompanyDTO;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.client.dto.FactoryDTO;
import com.jwipc.sys.client.dto.TaxDTO;
import com.jwipc.tender.client.dto.TenderDetailByIdDetailDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * Mro合同管理控制器
 */
@Controller
@RequestMapping(ModuleConst.MODULE_ROOT + "/mroManage/page")
@RequiredArgsConstructor
@Slf4j
public class ContractMroPageController {

    @Autowired
    ContractLogic contractLogic;

    @Autowired
    SequenceClient sequenceClient;

    @Autowired
    InquiryClient inquiryClient;

    @Autowired
    CompanyClient companyClient;

    @Autowired
    FactoryClient factoryClient;

    @Autowired
    SupplierClient supplierClient;

    @Autowired
    TaxClient taxClient;

    @Autowired
    UserPurchaseGroupClient userPurchaseGroupClient;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    TenderClient tenderClient;

    @Autowired
    DictClient dictClient;
    private final ContractSubSeqLogic contractSubSeqLogic;

    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("supplierFlag", false);
        return ModuleConst.MODULE_ROOT + "/mroManage/index";
    }

    @RequestMapping("/report/index")
    public String reportIndex(Model model){
        model.addAttribute("supplierFlag", false);
        return ModuleConst.MODULE_ROOT + "/mroManage/report/index";
    }


    @RequestMapping("/supplier/index")
    public String supplierIndex(Model model){
        model.addAttribute("supplierFlag", true);
        return ModuleConst.MODULE_ROOT + "/mroManage/index";
    }



    @AuditLogInter(value = "新增或编辑", module = "合同主数据")
    @RequestMapping("/form")
    public String form( Model model, String id,Integer check, Integer optType) {
        ContractDTO bean = contractLogic.formDeatil(id) ;
        if(StringUtils.isEmpty(id)){
//            String code = sequenceClient.createSequenceNo("contract_code");
            String code = sequenceClient.createSequenceNo("contract_code");
            model.addAttribute("code", code);
        }
        if (optType == 2) {
            // 发起变更
            String code = contractSubSeqLogic.getTempSubContractCode(bean.getContractCode());
            model.addAttribute("code", code);
            bean.setId(null);
            bean.setContractType("07");
            bean.setAssociationContract(bean.getContractCode());
            bean.setContractCode(code);
        } else if (optType == 4) {
            // 发起终止
            String code = contractSubSeqLogic.getTempSubContractCode(bean.getContractCode());
            bean.setId(null);
            bean.setContractType("08");
            bean.setAssociationContract(bean.getContractCode());
            bean.setContractCode(code);
            bean.setContractFiles(null);
            bean.setContractApplyContent(null);
            bean.setSignFile(null);
            bean.setContractSignFiels(null);
            bean.setContractSignFileStatue("0");
        }
        model.addAttribute("optType", optType);
        CurrentUserDTO currentUserDTO = LoginUtil.getCurrentUser();
        model.addAttribute("userName", currentUserDTO.getName());
        model.addAttribute("userAccount", LoginUtil.getAccount());
        model.addAttribute("userDeptName", currentUserDTO.getDeptName());
        model.addAttribute("bean", bean);
        model.addAttribute("check", check);
        return ModuleConst.MODULE_ROOT + "/mroManage/form";
    }

    @AuditLogInter(value = "查看", module = "MRO合同主数据")
    @RequestMapping("/look")
    public String LOOK( Model model, String id,Integer check) {
        ContractDTO bean = contractLogic.formDeatil(id) ;
        if(StringUtils.isEmpty(id)){
//            String code = sequenceClient.createSequenceNo("contract_code");
            String code = sequenceClient.createSequenceNo("contract_code");
            model.addAttribute("code", code);
        }
        CurrentUserDTO currentUserDTO = LoginUtil.getCurrentUser();
        model.addAttribute("userName", currentUserDTO.getLoginName());
        model.addAttribute("userAccount", LoginUtil.getAccount());
        model.addAttribute("userDeptName", currentUserDTO.getDeptName());
        model.addAttribute("bean", bean);
        model.addAttribute("check", check);
        model.addAttribute("optType", 3);
        return ModuleConst.MODULE_ROOT + "/mroManage/look";
    }


    @RequestMapping("/formDeatilById")
    public String formDeatilById( Model model,String supplierId,String supplierCode,String supplierName,String uuidKey, Integer check) {
        InquiryDetailByIdDTO detail = null;
        String rowKeyValue = (String)redisTemplate.opsForValue().get(uuidKey);
        List<InquiryDetailByIdDTO> list = JSON.parseArray(rowKeyValue,InquiryDetailByIdDTO.class);
        Map<String,List<InquiryDetailByIdDTO>> maps = list.stream().collect(Collectors.groupingBy(InquiryDetailByIdDTO::getSupplierId));
        List<InquiryDetailByIdDTO> details = maps.get(supplierId);
        detail = details.get(0);
        if(!StringUtils.isEmpty(supplierCode)){
            detail.setSupplierCode(supplierCode);
            detail.setContractSupplierCode(supplierCode);
        }
        if(!StringUtils.isEmpty(supplierName)){
            detail.setSupplierName(supplierName);
            detail.setContractSupplierName(supplierName);

        }
        List<ContractDetailDTO> items = new ArrayList<>();
        if(detail.getDataSources().equals(ContractConst.DATASOURCES_XJ)){
            List<InquiryDetailByIdDetailClientDTO> detailByIdDetailPOS = inquiryClient.formDeatilById(detail.getId(),detail.getSupplierId());
            items = JSON.parseArray(JSON.toJSONString(detailByIdDetailPOS),ContractDetailDTO.class);
            detail.setDataSources(2);
        } else if(detail.getDataSources().equals(ContractConst.DATASOURCES_ZB)) {
            List<TenderDetailByIdDetailDTO> detailByIdDetailPOS = tenderClient.formDeatilById(detail.getId(),detail.getSupplierId());
            items = JSON.parseArray(JSON.toJSONString(detailByIdDetailPOS),ContractDetailDTO.class);
            detail.setDataSources(1);
        }
        CompanyDTO companyDTO = companyClient.getByCode(detail.getContractCompanyCode());
        if(companyDTO!=null){
            detail.setContractCompanyName(companyDTO.getCompanyName());
        }
        model.addAttribute("details", null);
        final BigDecimal[] contractAmount = {BigDecimal.ZERO};
        if(CollectionUtils.isNotEmpty(items)){
            items.stream().forEach(a->{
                FactoryDTO factoryDTO = factoryClient.getByCode(a.getFactoryCode());
                TaxDTO taxDTO = taxClient.getByCode(a.getTaxRateCode());
                if(!StringUtils.isEmpty(taxDTO)){
                    a.setTaxRateName(taxDTO.getTaxName());
                }
                if(!StringUtils.isEmpty(factoryDTO)){
                    a.setFactoryName(factoryDTO.getName());
                }
                List<DictDTO> subs = dictClient.getDicByType("stock_point");
                Map<String, String> subMap = subs.stream().collect(Collectors.toMap(DictDTO::getCode,DictDTO::getName,(key1,key2)->key2));
                a.setStockPointName(subMap.get(a.getStockPoint()));
                contractAmount[0] = contractAmount[0].add(new BigDecimal(a.getTotle())).setScale(4,BigDecimal.ROUND_HALF_UP);
                a.setMaterialName(!StringUtils.isEmpty(a.getMaterialName())?a.getMaterialName().replace("'",""):"");
                a.setMaterialModel(!StringUtils.isEmpty(a.getMaterialModel())?a.getMaterialModel().replace("'",""):"");
                a.setMaterialSpec(!StringUtils.isEmpty(a.getMaterialSpec())?a.getMaterialSpec().replace("'",""):"");
            });
            detail.setCurrency(items.get(0).getCurrencyCode());
            detail.setContractAmount(contractAmount[0]);
            model.addAttribute("details", JSON.toJSONString(detail.getItems()));
        }
//        String code = sequenceClient.createSequenceNo("contract_code");
        String code = sequenceClient.createSequenceNo("contract_code");
        detail.setContractCode(code);
        CurrentUserDTO currentUserDTO = LoginUtil.getCurrentUser();
        model.addAttribute("userName", currentUserDTO.getName());
        model.addAttribute("userAccount", LoginUtil.getAccount());
        model.addAttribute("userDeptName", currentUserDTO.getDeptName());
        detail.setId(null);
        model.addAttribute("bean", detail);
        model.addAttribute("items", JSON.toJSONString(items));
        model.addAttribute("check", check);
        return ModuleConst.MODULE_ROOT + "/mroManage/formDeatilById";
    }

    @RequestMapping("/formBatchDetailByIds")
    public String formBatchDetailByIds( Model model,String ids,String supplierId,String supplierCode,
                                        String supplierName,String uuidKey, Integer check, String tmIdList,String companyCode) {
        InquiryDetailByIdDTO detail = new InquiryDetailByIdDTO();
        if(!StringUtils.isEmpty(supplierCode)){
            detail.setSupplierCode(supplierCode);
            detail.setContractSupplierCode(supplierCode);
        }
        if(!StringUtils.isEmpty(supplierName)){
            detail.setSupplierName(supplierName);
            detail.setContractSupplierName(supplierName);
        }
        List<ContractDetailDTO> items = new ArrayList<>();
        List<String> nos = new ArrayList<>();
        List<String> inquiryIdList =  StrUtil.split(ids, ",");
        List<InquiryDetailByIdDetailClientDTO> detailByIdDetailPOS = inquiryClient.formDetailByMaterialSupplierId(inquiryIdList,supplierId);
        List<String> tmIdsList =  StrUtil.split(tmIdList, ",");
        if(!CollectionUtils.isEmpty(tmIdsList)){
            detailByIdDetailPOS=detailByIdDetailPOS.stream()
                    .filter(detail1 -> tmIdsList.stream().anyMatch(keyword -> detail1.getTmId().toString().contains(keyword)))
                    .collect(Collectors.toList());
        }
        detailByIdDetailPOS.forEach(inquiryDetailByIdDetailClientDTO -> {
            nos.add(inquiryDetailByIdDetailClientDTO.getDataSourcesNo());
        });
        if (CollectionUtils.isNotEmpty(nos)){
            detail.setDataSourcesNo(org.apache.commons.lang3.StringUtils.join(nos, ","));
        }
        items = JSON.parseArray(JSON.toJSONString(detailByIdDetailPOS),ContractDetailDTO.class);
        detail.setDataSources(3);
        detail.setContractCompanyCode(companyCode);
        CompanyDTO companyDTO = companyClient.getByCode(detail.getContractCompanyCode());
        if(companyDTO!=null){
            detail.setContractCompanyName(companyDTO.getCompanyName());
        }
        model.addAttribute("details", null);
        final BigDecimal[] contractAmount = {BigDecimal.ZERO};
        if(CollectionUtils.isNotEmpty(items)){
            items.stream().forEach(a->{
                FactoryDTO factoryDTO = factoryClient.getByCode(a.getFactoryCode());
                TaxDTO taxDTO = taxClient.getByCode(a.getTaxRateCode());
                if(!StringUtils.isEmpty(taxDTO)){
                    a.setTaxRateName(taxDTO.getTaxName());
                }
                if(!StringUtils.isEmpty(factoryDTO)){
                    a.setFactoryName(factoryDTO.getName());
                }
                List<DictDTO> subs = dictClient.getDicByType("stock_point");
                Map<String, String> subMap = subs.stream().collect(Collectors.toMap(DictDTO::getCode,DictDTO::getName,(key1,key2)->key2));
                a.setStockPointName(subMap.get(a.getStockPoint()));
                contractAmount[0] = contractAmount[0].add(new BigDecimal(a.getTotle())).setScale(4,BigDecimal.ROUND_HALF_UP);
                a.setMaterialName(!StringUtils.isEmpty(a.getMaterialName())?a.getMaterialName().replace("'",""):"");
                a.setMaterialModel(!StringUtils.isEmpty(a.getMaterialModel())?a.getMaterialModel().replace("'",""):"");
                a.setMaterialSpec(!StringUtils.isEmpty(a.getMaterialSpec())?a.getMaterialSpec().replace("'",""):"");
            });
            detail.setCurrency(items.get(0).getCurrencyCode());
            detail.setContractAmount(contractAmount[0]);
            model.addAttribute("details", JSON.toJSONString(detail.getItems()));
        }
//        String code = sequenceClient.createSequenceNo("contract_code");
        String code = sequenceClient.createSequenceNo("contract_code");

        detail.setContractCode(code);
        CurrentUserDTO currentUserDTO = LoginUtil.getCurrentUser();
        model.addAttribute("userName", currentUserDTO.getLoginName());
        model.addAttribute("userAccount", LoginUtil.getAccount());
        model.addAttribute("userDeptName", currentUserDTO.getDeptName());
        model.addAttribute("bean", detail);
        model.addAttribute("items", JSON.toJSONString(items));
        model.addAttribute("check", check);
        return ModuleConst.MODULE_ROOT + "/mroManage/formDeatilById";
    }



    @RequestMapping("/choseContract")
    public String choseContract( Model model) {
        return ModuleConst.MODULE_ROOT + "/mroManage/choseContract";
    }


    @RequestMapping("/formPay")
    public String fromPayDetail(Model model, Integer conId, Long rowId,String paymentStage,
                                String paymentTime , BigDecimal paymentRatio,String remark) {
        model.addAttribute("rowId", rowId);
        model.addAttribute("paymentStage", paymentStage);
        model.addAttribute("paymentTime", paymentTime);
        model.addAttribute("paymentRatio", paymentRatio!=null?paymentRatio:BigDecimal.ZERO);
        model.addAttribute("conId", conId);
        model.addAttribute("remark", remark);
        return ModuleConst.MODULE_ROOT + "/mroManage/formPay";
    }


    @RequestMapping("/formDetail")
    public String formDeatil( Model model, String detailId,String isSap,Integer isMro,String subjectCode,String costCenterCode,String costCenterName,String materialName,String materialGroupCode,String materialGroupName,String materialCategory,String materialSpec,Integer warrantyPeriod,String materialModel,String materialBrand,String basisUnit,String price,String num,String taxRateName,String cardNumber,String taxRateCode,String bz,String currencyCode,String purchaseCode,String factoryCode,String factoryName,String itemCode,String customerCode,String customerName,String driverAsset,String teamName,String requireName) {
        ContractDetailDTO detail=null ;
        if(StringUtils.isEmpty(detailId) || detailId.equals("undefined")){
            if(!StringUtils.isEmpty(subjectCode)) {
                detail =new ContractDetailDTO();
                detail.setSubjectCode(subjectCode.equals("undefined")?null:subjectCode);
                //detail.setMaterialCode(materialCode);
                detail.setMaterialName(materialName);
                detail.setMaterialGroupCode(materialGroupCode);
                detail.setMaterialGroupName(materialGroupName);
                detail.setMaterialCategory(materialCategory.equals("undefined")?null:materialCategory);
                detail.setMaterialSpec(materialSpec.equals("undefined")?null:materialSpec);
                detail.setWarrantyPeriod(warrantyPeriod==null?null:warrantyPeriod);
                detail.setMaterialModel(materialModel.equals("undefined")?null:materialSpec);
                detail.setMaterialBrand(materialBrand.equals("undefined")?null:materialBrand);
                detail.setBasisUnit(basisUnit);
                detail.setPrice(StringUtils.isEmpty(price)||price.equals("undefined") ? BigDecimal.ZERO : new BigDecimal(price));
                detail.setNum(StringUtils.isEmpty(num)||num.equals("undefined")  ? BigDecimal.ZERO:new BigDecimal(num));
                detail.setTaxRateName(taxRateName);
                detail.setTaxRateCode(taxRateCode);
                detail.setCardNumber(cardNumber.equals("undefined")?null:cardNumber);
                detail.setPurchaseCode(purchaseCode.equals("undefined")?null:purchaseCode);
                detail.setItemCode(itemCode.equals("undefined")?null:itemCode);
                detail.setFactoryCode(factoryCode==null?"":factoryCode);
                detail.setFactoryName(factoryName==null?"":factoryName);
                detail.setBz(bz.equals("undefined")?null:bz);
                detail.setCurrencyCode(currencyCode);
                detail.setCustomerCode(customerCode.equals("undefined")?null:customerCode);
                detail.setCustomerName(customerName.equals("undefined")?null:customerName);
                detail.setDriverAsset(driverAsset.equals("undefined")?null:driverAsset);
                detail.setTeamName(teamName.equals("undefined")?null:teamName);
                detail.setRequireName(requireName.equals("undefined")?null:requireName);
                detail.setCostCenterCode(costCenterName.equals("undefined")?null:costCenterCode);
                detail.setCostCenterName(costCenterName.equals("undefined")?null:costCenterName);
            }

        }else{
            detail = contractLogic.formDetail(detailId);
            detail.setSubjectCode(subjectCode.equals("undefined")?null:subjectCode);
            //detail.setMaterialCode(materialCode);
            detail.setMaterialName(materialName);
            detail.setMaterialGroupCode(materialGroupCode);
            detail.setMaterialGroupName(materialGroupName);
            detail.setMaterialCategory(materialCategory.equals("undefined")?null:materialCategory);
            detail.setMaterialSpec(materialSpec.equals("undefined")?null:materialSpec);
            detail.setWarrantyPeriod(warrantyPeriod==null?null:warrantyPeriod);
            detail.setMaterialModel(materialModel.equals("undefined")?null:materialSpec);
            detail.setMaterialBrand(materialBrand.equals("undefined")?null:materialBrand);
            detail.setBasisUnit(basisUnit);
            detail.setPrice(StringUtils.isEmpty(price)||price.equals("undefined") ? BigDecimal.ZERO : new BigDecimal(price));
            detail.setNum(StringUtils.isEmpty(num)||num.equals("undefined")  ? BigDecimal.ZERO:new BigDecimal(num));
            detail.setTaxRateName(taxRateName);
            detail.setTaxRateCode(taxRateCode);
            detail.setCardNumber(cardNumber.equals("undefined")?null:cardNumber);
            detail.setPurchaseCode(purchaseCode.equals("undefined")?null:purchaseCode);
            detail.setItemCode(itemCode.equals("undefined")?null:itemCode);
            detail.setFactoryCode(factoryCode);
            detail.setFactoryName(factoryName);
            detail.setBz(bz.equals("undefined")?null:bz);
            detail.setCurrencyCode(currencyCode);
            detail.setCustomerCode(customerCode.equals("undefined")?null:customerCode);
            detail.setCustomerName(customerName.equals("undefined")?null:customerName);
            detail.setDriverAsset(driverAsset.equals("undefined")?null:driverAsset);
            detail.setTeamName(teamName);
            detail.setRequireName(requireName);
            detail.setCostCenterCode(costCenterCode.equals("undefined")?null:costCenterCode);
            detail.setCostCenterName(costCenterName.equals("undefined")?null:costCenterName);
        }
        model.addAttribute("detail", detail);
        model.addAttribute("isSap", isSap);
        model.addAttribute("isMro", isMro==null?1:isMro);
        return ModuleConst.MODULE_ROOT + "/mroManage/formDetail";
    }


    @RequestMapping("/formDetailMro")
    public String formDetailMro(Model model, String detailId, Long conId, Long rowId, String name, String num, String signTime, String ourPeople, String otherPeople, BigDecimal amount) {
       if(StringUtils.isEmpty(detailId)){
           ContractMroDTO dto = new ContractMroDTO();
           dto.setContractId(conId);
           dto.setName(name);
           dto.setNum(num);
           dto.setAmount(amount);
           DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
           if(!StringUtils.isEmpty(signTime)){
               dto.setSignTime( LocalDate.parse(signTime, formatter));
           }
           dto.setOtherPeople(otherPeople);
           dto.setOurPeople(ourPeople);
           model.addAttribute("detail", dto);
       }else{
           ContractMroDTO mroDTO = contractLogic.formDetailMro(detailId);
           model.addAttribute("detail",mroDTO);
       }
        return ModuleConst.MODULE_ROOT + "/mroManage/formDetailMro";
    }

    @GetMapping("/updateTimePage")
    public String updateTimePage(String ids, Model model){
        model.addAttribute("ids",ids);
        return ModuleConst.MODULE_ROOT + "/mroManage/report/update_time_page";
    }

    @AuditLogInter(value = "合同打印", module = "MRO类合同")
    @GetMapping("/print")
    public String printDo(Model model, String contractId) {
        List<ContractPrintDTO> printDTOS =
                contractLogic.getPrintData(contractId);
        model.addAttribute("contract", printDTOS);

        return ModuleConst.MODULE_ROOT + "/mroManage/print_template";
    }


    @GetMapping("/changeContractConfirmPage")
    public String changeContractConfirmPage(Model model, String id){
        model.addAttribute("id", id);
        return ModuleConst.MODULE_ROOT + "/mroManage/changeContractConfirm";
    }
}
