package com.jwipc.finance.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.jwipc.constant.DictCode;
import com.jwipc.finance.convert.ReceiptVoucherConvert;
import com.jwipc.finance.dto.AccountStatementDTO;
import com.jwipc.finance.dto.StatementItemDTO;
import com.jwipc.finance.logic.AccountStatementDetailLogic;
import com.jwipc.finance.logic.AccountStatementLogic;
import com.jwipc.log.annotation.AuditLogInter;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.clent.dto.SupplierContactsDTO;
import com.jwipc.supplier.clent.dto.SupplierDTO;
import com.jwipc.supplier.clent.dto.SupplierPurchaseCategoryDTO;
import com.jwipc.supplier.client.SupplierClient;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.dto.AttachmentTypeConfigDTO;
import com.jwipc.sys.logic.AttachmentTypeConfigLogic;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.jwipc.finance.constant.ModuleConst.MODULE_ROOT;

/**
 * <p>
 *     对账模块-对账单 前端控制器
 * </p>
 *
 * @author JT
 * @since 2020-07-31
 */
@Controller
@RequestMapping(MODULE_ROOT + "/account/statement")
@RequiredArgsConstructor
public class AccountStatementPageController {
    private final AccountStatementLogic accountStatementLogic;
    private final AccountStatementDetailLogic accountStatementDetailLogic;
    private final SupplierClient supplierClient;
    private final AttachmentTypeConfigLogic attachmentTypeConfigLogic;
    private final DictClient dictClient;
    private final ReceiptVoucherConvert receiptVoucherConvert;
    /**
     * 采购对账单管理
     *
     * @param model model
     * @return 页面
     */
    @AuditLogInter(value = "采购对账确认首页", module = "对账单")
    @GetMapping("/purchase/index")
    public String purchaseIndex(Model model,String status){
        // 角色类型 1:采购角色 2:财务角色
        model.addAttribute("status", status);
        model.addAttribute("roleType", 1);
        model.addAttribute("userId", LoginUtil.getUserId());
        return MODULE_ROOT + "/statement/index_purchase";
    }

    /**
     * 打印开票单据-财务到票确认
     * @param id 开票id
     * @return
     */
    @GetMapping("/print")
    public String printStatement(Long id, Model model){

        Map<String,Object> map = accountStatementLogic.printStatement(id);
        for(String key:map.keySet()){
            model.addAttribute(key,map.get(key));
        }

        return MODULE_ROOT +  "/statement/statement_print3";
    }

    /**
     * 财务对账单管理
     *
     * @param model model
     * @return 页面
     */
    @AuditLogInter(value = "财务对账确认首页", module = "对账单")
    @GetMapping("/finance/index")
    public String index(Model model){
        // 角色类型 1:采购角色 2:财务角色
        model.addAttribute("roleType", 2);
        model.addAttribute("userId", LoginUtil.getUserId());
        return MODULE_ROOT +  "/statement/index_finance";
    }


    /**
     * 材料对账首页
     *
     * @param model model
     * @return 页面
     */
    @AuditLogInter(value = "订单对账列表页", module = "对账单")
    @GetMapping("/material/index")
    public String materialIndex(Model model){
        if(!LoginUtil.isSupplier()){
            model.addAttribute("isSupplier", 0);
        }else {
            model.addAttribute("isSupplier", 1);
//            // 限制新增对账标识 0:不限制 1:限制
//            model.addAttribute("restrictFlag", vpsConfigService.checkSupRestrict(loginUser.getLoginName(), 1));
        }

        model.addAttribute("orderType", 1);
        model.addAttribute("userId", LoginUtil.getUserId());
        return MODULE_ROOT + "/statement/index_sup";
    }

    /**
     * 对账单采购审批确认时选择扣款信息弹框
     *
     * @param model model
     * @return 页面
     */
    @GetMapping("/chose/statement/dialog")
    public String choseStatementDialog(Model model){
        if(LoginUtil.isSupplier()){
            model.addAttribute("supplierCode", LoginUtil.getAccount());
        }
        model.addAttribute("isSupplier", LoginUtil.isSupplier()?1:0);
        model.addAttribute("userId", LoginUtil.getUserId());
        return MODULE_ROOT + "/statement/_chose_statement";
    }

    /**
     * 对账单采购审批确认时选择扣款信息弹框
     *
     * @param model model
     * @return 页面
     */
    @GetMapping("/chose/statement/with/apply/dialog")
    public String choseStatementWithApplyDialog(Model model,String companyCode,String supplierCode,String currencyCode,String paymentWay){
        model.addAttribute("supplierCode", supplierCode);
        model.addAttribute("companyCode", companyCode);
        model.addAttribute("currencyCode", currencyCode);
        model.addAttribute("paymentWay", paymentWay);
        return MODULE_ROOT + "/statement/_chose_statement_with_apply";
    }

    /**
     * 对账单新增页面
     *
     * @param model model
     * @param orderType 对账单类型 1:材料商对账单 2:承运商对账单
     * @param optType 操作类型；0-新增；1-编辑；2-查看；3-主管确认；4-财务确认
     * @return 页面
     */
    @GetMapping("/detail")
    public String detail(Model model, Integer orderType, Integer optType,Integer optMenu, Long id){
        AccountStatementDTO data = new AccountStatementDTO();
        if (id!=null){
            data = accountStatementLogic.getById(id);
            data.setDifferenceAmount(data.getTaxAmount().subtract(data.getNotTaxAmount()));
            model.addAttribute("inStockStartDate", DateUtil.format(data.getInStockStartDate(),"yyyy-MM-dd"));
            model.addAttribute("inStockEndDate", DateUtil.format(data.getInStockEndDate(),"yyyy-MM-dd"));
            SupplierDTO supplierDTO = supplierClient.getSupplierByCode(data.getSupplierCode());
            if (ObjectUtil.isNotNull(supplierDTO)){
                model.addAttribute("supplierGroup", supplierDTO.getSupplierGroup());
            }

        }else {
            data.setAccountStatementYear(DateUtil.format(DateUtil.offsetMonth(new Date(),-1),"YYYY"));
            data.setAccountStatementMonth(DateUtil.format(DateUtil.offsetMonth(new Date(),-1),"MM"));
            data.setVoucherType(1);
            if(LoginUtil.isSupplier()){
                SupplierDTO supplierDTO = supplierClient.getSupplierByCode(LoginUtil.getAccount());
                if (ObjectUtil.isNotNull(supplierDTO)){
                    model.addAttribute("supplierGroup", supplierDTO.getSupplierGroup());
                }
                List<SupplierPurchaseCategoryDTO> supplierPurchaseCategoryDTOS = supplierClient.getList(String.valueOf(LoginUtil.getSupplierId()));
                if (CollectionUtil.isNotEmpty(supplierPurchaseCategoryDTOS)){
                    //过滤优先标记
                    List<SupplierPurchaseCategoryDTO> filterSupplierPurchaseCategoryDTOS = supplierPurchaseCategoryDTOS.stream().filter(supplierPurchaseCategoryDTO -> supplierPurchaseCategoryDTO.getFirstFlag()==1).toList();
                    if (CollectionUtil.isEmpty(filterSupplierPurchaseCategoryDTOS)){
                        //过滤公司
                        List<SupplierPurchaseCategoryDTO> filterCompanyDTOS = supplierPurchaseCategoryDTOS.stream().filter(supplierPurchaseCategoryDTO -> "1000".equals(supplierPurchaseCategoryDTO.getCompanyCode())).toList();
                        if (CollectionUtil.isNotEmpty(filterCompanyDTOS)){
                            data.setCompanyCode(filterCompanyDTOS.get(0).getCompanyCode());
                            data.setCurrencyCode(filterCompanyDTOS.get(0).getCurrencyCode());
                            data.setTaxCode(filterCompanyDTOS.get(0).getTaxCode());
                            data.setPaymentTermCode(filterCompanyDTOS.get(0).getPaymentTerms());
                            data.setPaymentWay(filterCompanyDTOS.get(0).getPaymentMethod());
                            data.setPurchaseGroup(filterCompanyDTOS.get(0).getPurchaseGroupCode());
                        }else {
                            data.setCompanyCode(supplierPurchaseCategoryDTOS.get(0).getCompanyCode());
                            data.setCurrencyCode(supplierPurchaseCategoryDTOS.get(0).getCurrencyCode());
                            data.setTaxCode(supplierPurchaseCategoryDTOS.get(0).getTaxCode());
                            data.setPaymentTermCode(supplierPurchaseCategoryDTOS.get(0).getPaymentTerms());
                            data.setPaymentWay(supplierPurchaseCategoryDTOS.get(0).getPaymentMethod());
                            data.setPurchaseGroup(supplierPurchaseCategoryDTOS.get(0).getPurchaseGroupCode());
                        }
                    }else {
                        data.setCompanyCode(filterSupplierPurchaseCategoryDTOS.get(0).getCompanyCode());
                        data.setCurrencyCode(filterSupplierPurchaseCategoryDTOS.get(0).getCurrencyCode());
                        data.setTaxCode(filterSupplierPurchaseCategoryDTOS.get(0).getTaxCode());
                        data.setPaymentTermCode(filterSupplierPurchaseCategoryDTOS.get(0).getPaymentTerms());
                        data.setPaymentWay(filterSupplierPurchaseCategoryDTOS.get(0).getPaymentMethod());
                        data.setPurchaseGroup(filterSupplierPurchaseCategoryDTOS.get(0).getPurchaseGroupCode());
                    }

                }
            }
        }
        model.addAttribute("data", data);
        if(LoginUtil.isSupplier()){
            String account = LoginUtil.getAccount();
            model.addAttribute("supplierCode", account);
            SupplierDTO supplierByCode = supplierClient.getSupplierByCode(account);
            if(supplierByCode!=null){
                model.addAttribute("supplierName", supplierByCode.getSupplierName());
            }
        }
        //操作类型
        model.addAttribute("optType", optType);
        model.addAttribute("lookFlag", optType==2||optType==3||optType==4);
        model.addAttribute("manualCheckShowFlag", optType==2||optType==3||optType==4);
        model.addAttribute("isSupplier", LoginUtil.isSupplier() ? 1 : 0);
        model.addAttribute("orderType", orderType);
        //附件清单是否显示；0-显示；1-不显示
        int tbAttachmentLookFlag = 0;
        //如果是外币对账单
        if (StrUtil.isNotEmpty(data.getCurrencyCode())&&!data.getCurrencyCode().equals("CNY")){
            if (optMenu==0||optMenu==1){
                tbAttachmentLookFlag = 1;
            }
        }
        if (Objects.equals(LoginUtil.getAccount(), "admin")){
            tbAttachmentLookFlag = 0;
        }
        model.addAttribute("tbAttachmentLookFlag", tbAttachmentLookFlag);

        List<AttachmentTypeConfigDTO> attachmentTypeCreateConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("account_statement_create");
        List<AttachmentTypeConfigDTO> attachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("account_statement_check");
        model.addAttribute("attachmentTypeCreateConfigs", JSONUtil.toJsonStr(attachmentTypeCreateConfigs));
        model.addAttribute("attachmentTypeCheckConfigs", JSONUtil.toJsonStr(attachmentTypeCheckConfigs));
        List<AttachmentTypeConfigDTO> overseasAttachmentTypeCreateConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("overseas_account_statement_create");
        List<AttachmentTypeConfigDTO> overseasAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("overseas_account_statement_check");
        model.addAttribute("overseasAttachmentTypeCreateConfigs", JSONUtil.toJsonStr(overseasAttachmentTypeCreateConfigs));
        model.addAttribute("overseasAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(overseasAttachmentTypeCheckConfigs));

        //对账单银行转账或外来对冲(人工检查)校验
        List<AttachmentTypeConfigDTO> transferAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("transfer_account_statement_check");
        model.addAttribute("transferAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(transferAttachmentTypeCheckConfigs));
        //对账单承兑汇票(人工检查)校验
        List<AttachmentTypeConfigDTO> acceptanceAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("acceptance_account_statement_check");
        model.addAttribute("acceptanceAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(acceptanceAttachmentTypeCheckConfigs));
        //对账单银行转账(人工检查)校验
        List<AttachmentTypeConfigDTO> overseasTransferAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("overseas_transfer_account_statement_check");
        model.addAttribute("overseasTransferAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(overseasTransferAttachmentTypeCheckConfigs));

        //关联方加工费带出
        List<AttachmentTypeConfigDTO> correlationAttachmentTypeCreateConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("correlation_account_statement_create");
        model.addAttribute("correlationAttachmentTypeCreateConfigs", JSONUtil.toJsonStr(correlationAttachmentTypeCreateConfigs));
        //关联方加工费校验
        List<AttachmentTypeConfigDTO> correlationAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("correlation_account_statement_check");
        model.addAttribute("correlationAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(correlationAttachmentTypeCheckConfigs));
        //关联方加工费人工检查
        List<AttachmentTypeConfigDTO> correlationAttachmentTypeManualCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("correlation_account_statement_check");
        model.addAttribute("correlationAttachmentTypeManualCheckConfigs", JSONUtil.toJsonStr(correlationAttachmentTypeManualCheckConfigs));

        //sto加工费带出
        List<AttachmentTypeConfigDTO> stoAttachmentTypeCreateConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("sto_account_statement_create");
        model.addAttribute("stoAttachmentTypeCreateConfigs", JSONUtil.toJsonStr(stoAttachmentTypeCreateConfigs));
        //sto加工费校验
        List<AttachmentTypeConfigDTO> stoAttachmentTypeCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("sto_account_statement_check");
        model.addAttribute("stoAttachmentTypeCheckConfigs", JSONUtil.toJsonStr(stoAttachmentTypeCheckConfigs));
        //sto加工费人工检查
        List<AttachmentTypeConfigDTO> stoAttachmentTypeManualCheckConfigs = attachmentTypeConfigLogic.listByBusinessTypeCode("sto_account_statement_check");
        model.addAttribute("stoAttachmentTypeManualCheckConfigs", JSONUtil.toJsonStr(stoAttachmentTypeManualCheckConfigs));
        return MODULE_ROOT + "/statement/detail";
    }


    /**
     * 所有对账单列表(供应商对账单)
     *
     * @param model model
     * @return 页面
     */
    @GetMapping("/index/all")
    public String indexAll(Model model){
        if(!LoginUtil.isSupplier()){
            model.addAttribute("isSupplier", 0);
        }else {
            model.addAttribute("isSupplier", 1);
        }
        return MODULE_ROOT + "/statement/index_all";
    }



    /**
     * 对账管理中选择返利信息弹框
     *
     * @param model model
     * @param companyCode 公司编码
     * @param supplierCode 供应商编码
     * @param selectedRmId 已选择的返利记录ID
     * @param tempDelRmId 临时删除的返利记录ID
     * @return 页面
     */
    @GetMapping("/chose/rebate/dialog")
    public String choseRebateDialog(Model model, String companyCode, String supplierCode, String selectedRmId, String tempDelRmId){
        model.addAttribute("companyCode", companyCode);
        model.addAttribute("supplierCode", supplierCode);
        model.addAttribute("selectedRmId", selectedRmId);
        model.addAttribute("tempDelRmId", tempDelRmId);
        return MODULE_ROOT + "/statement/_chose_rebate";
    }

    @GetMapping("/contractFileUpload")
    public String contractFileUpload(Model model, String id){
        model.addAttribute("id", id);
        return MODULE_ROOT + "/statement/contract_file_upload";
    }


    /**
     * 对账单采购审批确认时选择扣款信息弹框
     *
     * @param model model
     * @param companyCode 公司编码
     * @param supplierCode 供应商编码
     * @param selectedDmId 已选择的返利记录ID
     * @param tempDelDmId 临时删除的返利记录ID
     * @return 页面
     */
    @GetMapping("/chose/deduction/dialog")
    public String choseDeductionDialog(Model model, String companyCode, String supplierCode, String selectedDmId, String tempDelDmId){
        model.addAttribute("companyCode", companyCode);
        model.addAttribute("supplierCode", supplierCode);
        model.addAttribute("selectedDmId", selectedDmId);
        model.addAttribute("tempDelDmId", tempDelDmId);
        return MODULE_ROOT + "/statement/_chose_deduction";
    }


    /**
     * 对账单编辑时选择入库凭证数据
     *
     * @param model model
     * @param orderType 对账单类型 1:材料商对账 2:承运商对账
     * @param companyCode 公司编码
     * @param factoryCode 工厂编码
     * @param supplierCode 供应商编码
     * @param currencyCode 货币代码
     * @param inStockStartDate 入库开始时间
     * @param inStockEndDate 入库结束时间
     * @param alreadyExistId 已选择的凭证ID
     * @param asId 对账单ID
     * @return 页面
     */
    @GetMapping("/chose/voucher/dialog")
    public String choseVoucherData(
            Model model, Integer orderType, String companyCode,String taxCode, String factoryCode, String supplierCode, String currencyCode,
            String inStockStartDate, String inStockEndDate, String alreadyExistId, Long asId,String purchaseGroup,Integer voucherType
    ){
        model.addAttribute("orderType", orderType);
        model.addAttribute("companyCode", companyCode);
        model.addAttribute("taxCode", taxCode);
        model.addAttribute("factoryCode", factoryCode);
        model.addAttribute("supplierCode", supplierCode);
        model.addAttribute("currencyCode", currencyCode);
        model.addAttribute("inStockStartDate", inStockStartDate);
        model.addAttribute("inStockEndDate", inStockEndDate);
        model.addAttribute("alreadyExistId", alreadyExistId);
        model.addAttribute("asId", asId);
        model.addAttribute("purchaseGroup", purchaseGroup);
        model.addAttribute("voucherType", voucherType);
        return MODULE_ROOT + "/statement/_chose_voucher";
    }

    /**
     *xiahs
     */
    @GetMapping("/purchase/salesContractsIndex")
    public String salesContractsIndex(Model model){
        model.addAttribute("userId", LoginUtil.getUserId());
        return MODULE_ROOT + "/statement/index_sales_contract";
    }
}
