package com.jwipc.finance.controller.rest;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jwipc.exception.DaoException;
import com.jwipc.finance.dto.*;
import com.jwipc.finance.entity.AccountStatement;
import com.jwipc.finance.entity.InvoicedApply;
import com.jwipc.finance.logic.AccountStatementLogic;
import com.jwipc.finance.model.query.AccountSalesContractsDetailQuery;
import com.jwipc.finance.model.query.AccountStatementQuery;
import com.jwipc.finance.model.query.InvoicedApplyQuery;
import com.jwipc.log.annotation.AuditLogInter;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.sys.entity.BusinessAttachment;
import com.jwipc.sys.model.po.BusinessAttachmentPO;
import com.jwipc.sys.model.query.BusinessAttachmentQuery;
import com.jwipc.util.EasyExcelUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

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

/**
 * <p>
 *     对账模块-对账单 前端控制器
 * </p>
 *
 * @author JT
 * @since 2020-07-31
 */
@RestController
@RequestMapping(MODULE_ROOT + "/account/statement/rest")
@RequiredArgsConstructor
public class AccountStatementRestController {
    private final AccountStatementLogic accountStatementLogic;

    /**
     * 查询对账单列表(采购或者财务)
     *
     * @param page 当前页码
     * @param rows 每页显示行数
     * @param query 查询条件
     * @return 结果
     */
    @AuditLogInter(value = "首页查询列表", module = "采购/财务对账确认")
    @PostMapping("/list")
    public PageView list(Integer page, Integer rows, AccountStatementQuery query){
        query.setIsSupplier(LoginUtil.isSupplier()?1:0);
        if (LoginUtil.isSupplier()){
            query.setSupplierCode(LoginUtil.getSupplierCode());
        }else {
            query.setUserId(LoginUtil.getUserId());
        }


        // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝 9:确认通过
        List<Integer> statusList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(query.getAsStatus())) {
            String[] statusArray = StringUtils.split(query.getAsStatus(), ",");
            for (String status: statusArray) {
                statusList.add(Integer.parseInt(status));
            }
        }else {
            // 角色类型 1:采购角色 -> 2:待采购确认 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝 9:确认通过
            if(null != query.getRoleType() && 1 == query.getRoleType()) {
                statusList.add(2);
                statusList.add(4);
                statusList.add(5);
                statusList.add(6);
                statusList.add(7);
                statusList.add(8);
                statusList.add(9);
                // 采购不看已经开票完成的数据
//                query.setIsComplete(0);
            }

            // 角色类型 2:财务角色 -> 7:待财务确认 9:确认通过
            if(null != query.getRoleType() && 2 == query.getRoleType()) {
                statusList.add(7);
                statusList.add(9);
            }
        }
        query.setStatusList(statusList);
        return accountStatementLogic.findByPage(query);
    }

    /**
     * 查询对账单列表(供应商)
     * @param query 查询条件
     * @return 结果
     */
    @AuditLogInter(value = "首页查询列表", module = "订单对账")
    @PostMapping("/sup/list")
    public PageView supList(AccountStatementQuery query){
        query.setIsSupplier(LoginUtil.isSupplier()?1:0);
        if(LoginUtil.isSupplier()){
            query.setSupplierCode(LoginUtil.getAccount());
            // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝
            List<Integer> statusList = Lists.newArrayList();
            statusList.add(9);
//            query.setStatusList(statusList);
        }else {
            query.setUserId(LoginUtil.getUserId());
            // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝
            List<Integer> statusList = Lists.newArrayList();
            statusList.add(1);
            statusList.add(2);
            statusList.add(3);
            statusList.add(4);
            statusList.add(5);
            statusList.add(6);
            statusList.add(7);
            statusList.add(8);
            statusList.add(9);
//            query.setStatusList(statusList);
        }
        return accountStatementLogic.findByPage(query);
    }

    /**
     * 导出
     * @param exportFiled 导出的列信息
     * @param queryStr 查询条件
     */
    @PostMapping("/sup/export")
    public void supExport(HttpServletResponse response, String exportFiled, String queryStr) throws IOException {
        AccountStatementQuery query = JSON.parseObject(queryStr, AccountStatementQuery.class);
        query.setIsSupplier(LoginUtil.isSupplier()?1:0);
        if(LoginUtil.isSupplier()){
            query.setSupplierCode(LoginUtil.getAccount());
            // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝
            List<Integer> statusList = Lists.newArrayList();
            statusList.add(9);
//            query.setStatusList(statusList);
        }else {
            query.setUserId(LoginUtil.getUserId());
            // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝
            List<Integer> statusList = Lists.newArrayList();
            statusList.add(1);
            statusList.add(2);
            statusList.add(3);
            statusList.add(4);
            statusList.add(5);
            statusList.add(6);
            statusList.add(7);
            statusList.add(8);
            statusList.add(9);
//            query.setStatusList(statusList);
        }
        // 查询数据列表，直接调用列表的查询，无需特殊改动
        final List<AccountStatementDTO> exportData = accountStatementLogic.listAll(query);
        //动态导出工具类，只需要修改导出excel名称
        EasyExcelUtils.trendsModelWrite(response,"订单对账-" + DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN),"sheet", exportData, exportFiled);
    }

    /**
     * 查询对账单列表(所有)
     *
     * @param query 查询条件
     * @return 结果
     */
    @PostMapping("/all/list")
    public PageView allList(AccountStatementQuery query){
        if(LoginUtil.isSupplier()){
            query.setSupplierCode(LoginUtil.getAccount());
            // 1:暂存 2:待采购确认 3:采购拒绝 4:待推送OA审批 5:OA审批中 6:OA审批不通过 7:待财务确认 8:财务拒绝
            List<Integer> statusList = Lists.newArrayList();
            statusList.add(9);
//            query.setStatusList(statusList);
        }else {
            query.setUserId(LoginUtil.getUserId());
        }
        return accountStatementLogic.findByPage(query);
    }

    /**
     * 查询对账单或开票申请列表
     * @param query 查询条件
     * @return 结果
     */
    @PostMapping("/account/or/apply/list")
    public List<AccountStatementDTO> accountOrApplyList(AccountStatementQuery query){
        return accountStatementLogic.accountOrApplyList(query);
    }


    /**
     * 对账单保存
     *
     * @param opyType 操作类型；0-新增；1-编辑；2-查看；3-主管确认；4-财务确认
     * @param headData 对账单抬头数据
     * @param statementItem 对账单明细数据
     * @param deductionIds 对账单扣款关系之扣款记录ID
     * @param rebateIds 对账单返利关系之返利记录ID
     * @return 结果
     */
    @AuditLogInter(value = "操作类型[opyType]：0-新增；1-编辑；2-查看；3-主管确认；4-财务确认", module = "对账单")
    @PostMapping("/saveOrUpdate")
    public ResponseEntity saveOrUpdate(Integer opyType,String headData, String statementItem,String businessAttachmentItem, String deductionIds, String rebateIds){
        accountStatementLogic.saveOrUpdate(opyType,headData,statementItem,businessAttachmentItem,deductionIds,rebateIds);
        return ResponseEntity.ok(true);
    }

    /**
     * 批量删除对账单
     *
     * @param ids 待删除的对账单ID
     * @return 结果
     */
    @PostMapping("/del")
    public ResponseEntity dataDel(String ids,Integer type){
        accountStatementLogic.dataDel(ids,type);
        return ResponseEntity.ok(true);
    }

    /**
     * 批量提交对账单进行确认
     *
     * @param ids 待删除的对账单ID
     * @return 结果
     */
    @PostMapping("/submit/confirm")
    public ResponseEntity submitConfirm(String ids){
        accountStatementLogic.submitConfirm(ids);
        return ResponseEntity.ok(true);
    }

    /**
     * 上传签章文件
     * @param signFile 文件id
     * @param id 对账单id
     */
    @RequestMapping("/saveSignFile")
    public ResponseEntity saveSignFile(Long signFile , Long id) {
//        if(files!=null&&files.length==0){
//            throw new DaoException("未上传盖章文件");
//        }
//        assert files != null;
        accountStatementLogic.saveSignFile(signFile,id);
        return ResponseEntity.ok(true);
    }
    @RequestMapping("/saveSignFile1")
    public ResponseEntity saveSignFile1(String signFile , Long id,String businessTypeCode) {
//        if(files!=null&&files.length==0){
//            throw new DaoException("未上传盖章文件");
//        }
//        assert files != null;
        accountStatementLogic.saveSignFile1(signFile,id,businessTypeCode);

        return ResponseEntity.ok(true);
    }

    /**
     * 一步发起签署
     * @param id 对账单id
     */
    @RequestMapping("/sendSign")
    public ResponseEntity sendSign(String id) {
        accountStatementLogic.sendSign(id);
        return ResponseEntity.ok(true);
    }


    /**
     * 对账单审批操作
     * fin/account/statement/rest/approve
     *
     * @return 结果
     */
    @PostMapping("/approve")
    public ResponseEntity approveOperation(@RequestBody AccountStatementApproveDTO params){

        accountStatementLogic.approveOperation(params);

        return ResponseEntity.ok(true);
    }

    @PostMapping("/approveCheck")
    public ResponseEntity approveCheck(@RequestBody AccountStatementApproveDTO params){

        return ResponseEntity.ok(accountStatementLogic.approveCheck(params));
    }

    /**
     * 采购撤销待财务确认状态的对账单
     *
     * @param asId 对账单ID
     * @param revokeReason 撤销原因
     * @return 结果
     */
    @PostMapping("/revoke/fin/confirm")
    public ResponseEntity revokeFinConfirm(Long asId, String revokeReason){
        accountStatementLogic.revokeFinConfirm(asId, revokeReason);
        return ResponseEntity.ok(true);
    }

    /**
     * 财务撤销已确认状态的对账单
     *
     * @param asId 对账单ID
     * @param revokeReason 撤销原因
     * @return 结果
     */
    @PostMapping("/revoke/fin/confirmed")
    public ResponseEntity revokeFinConfirmed(Long asId, String revokeReason){
        accountStatementLogic.revokeFinConfirmed(asId, revokeReason);
        return ResponseEntity.ok(true);
    }

    /**
     * 基于 供应商+公司+币别  获取应付未清项目余额
     */
    @PostMapping("payableOutstanding")
    public CopeWithUnclearDTO getCopeWithUnclear(String companyCode, String supplierCode, String currency, String inStockEndDate){
        return  accountStatementLogic.getCopeWithUnclear(companyCode,supplierCode,currency,inStockEndDate);
    }

    @PostMapping("payablePayment")
    public CopeWithUnclearDTO payablePayment(String companyCode, String supplierCode,String currencyCode){
        return  accountStatementLogic.payablePayment(companyCode,supplierCode,currencyCode);
    }

    /**
     * 修改付款备注
     */
    @PostMapping("/savePaymentRemark")
    public ResponseEntity savePaymentRemark(Long id,String paymentRemark){
        accountStatementLogic.savePaymentRemark(id,paymentRemark);
        return ResponseEntity.ok(true);
    }
    @AuditLogInter(value = "首页查询列表", module = "购销合同列表")
    @PostMapping("/salesContractList")
    public PageView salesContractList(Integer page, Integer rows, AccountSalesContractsDetailQuery query){

        return accountStatementLogic.findSalesContractByPage(query);
    }
    @AuditLogInter(value = "导出", module = "购销合同列表")
    @PostMapping("/detailExport")
    public void export(HttpServletResponse response, String exportFiled, String queryStr) throws IOException {

        exportFiled = exportFiled.replace("createDate", "createDateStr").replace("contractDate","contractDateStr");
        // 查询数据列表，直接调用列表的查询，无需特殊改动
        final List<AccountSalesContractsDetailDTO> exportData = accountStatementLogic.findSalesContractListAll(
                JSON.parseObject(queryStr, AccountSalesContractsDetailQuery.class));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for (AccountSalesContractsDetailDTO exportDatum : exportData) {
            exportDatum.setDelFlag(exportDatum.getDelFlag().equals("0") ? "正常" : "删除");
            exportDatum.setContractDateStr(exportDatum.getContractDate().format(formatter));
            exportDatum.setCreateDateStr(exportDatum.getCreateDate().format(formatter));
        }
        //动态导出工具类，只需要修改导出excel名称
        EasyExcelUtils.trendsModelWrite(response,
                "购销合同明细数据-" + DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN), "sheet", exportData,
                exportFiled);
    }


    /**
     * 查询对账单关联的相关订单及送货单附件
     * @param query ID
     * @return 附件数据
     */
    @RequestMapping("accountAttachmentList")
    public PageView accountAttachmentList(List<StatementItemDTO> query) {
//        final Page<BusinessAttachment> dbPage = PageUtil.toPage(query);
//        List<BusinessAttachmentPO> list = businessAttachmentService.queryByPage(dbPage, query);
//        accountStatementLogic.accountAttachmentList(query);
//        return PageUtil.getPV(list, dbPage.getTotal());
        return  null;
    }

    @PostMapping("/toImg")
    public ResponseEntity toImg(Long asId) {
        AccountStatementDTO accountStatement = accountStatementLogic.getById(asId);
        if (StringUtils.isNotEmpty(accountStatement.getImgCode())&&accountStatement.getImgTime()!=null){
            throw new DaoException("该对账单已影像化，不可重复操作");
        }
        accountStatementLogic.toImg(asId);
        return ResponseEntity.ok(true);
    }

    @PostMapping("/deleteImg")
    public ResponseEntity deleteImg(Long asId) {
        AccountStatementDTO accountStatement = accountStatementLogic.getById(asId);
        if (accountStatement.getImgTime()==null){
            throw new DaoException("该对账单未影像化，不可删除");
        }
        accountStatementLogic.deleteImg(asId);
        return ResponseEntity.ok(true);
    }
}
