package com.loan.system.controller.wechat;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.server.HttpServerResponse;
import com.loan.system.context.BaseContext;
import com.loan.system.domain.dto.DocumentDTO;
import com.loan.system.domain.entity.Contract;
import com.loan.system.domain.entity.Document;
import com.loan.system.domain.enums.ExceptionEnum;
import com.loan.system.domain.pojo.ContractInformation;
import com.loan.system.domain.vo.CustomerVO;
import com.loan.system.domain.vo.LoanCaseSimpleVO;
import com.loan.system.exception.DescribeException;
import com.loan.system.service.*;
import com.loan.system.utils.PoiWordUtil;
import com.loan.system.domain.enums.StepEnum;
import com.loan.system.domain.enums.StepPropertyEnum;
import com.loan.system.domain.pojo.Result;
import com.loan.system.domain.vo.ContractVO;
import com.loan.system.domain.vo.StepVO;
import com.loan.system.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.UUID;

import static com.loan.system.domain.enums.ExceptionEnum.STEP_HAS_NOT_PROCESS;
import static com.loan.system.domain.enums.ExceptionEnum.STEP_USER_NOT_EXPECTED;

@RestController
@RequestMapping("/wechat/contract")
@Api(tags = "合同签订接口")
public class ContractController {
    @Value("${upload.templatePath}")
    private String contractPath;

    @Autowired
    private ContractService contractService;
    @Autowired
    private StepService stepService;
    @Autowired
    private DocumentService documentService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private LoanService loanService;

    @GetMapping
    @ApiOperation("显示所有合同（内部人员）")
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result findContracts(@RequestParam Long caseId){
        return ResultUtil.success("success",contractService.findContractByCaseId(caseId));
    }
    @GetMapping("/{id}")
    @ApiOperation("显示合同文件详情（内部人员）")
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public void findContractsDetails(@PathVariable("id") Long contractId , @RequestParam Long caseId , HttpServletResponse response){
        //获取合同信息
        Contract contractById = contractService.findContractById(contractId);
        if(ObjectUtils.isEmpty(contractById))
            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);

        getContractInformation(response,caseId,BeanUtil.copyProperties(contractById,ContractVO.class));

    }

//    @GetMapping("/{contractSeq}")
//    @ApiOperation("显示合同表详情（内部人员）")
//    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
//    public Result findContractsDetails(@PathVariable("contractSeq") Integer contractSeq , @RequestParam Long caseId , HttpServletResponse response){
//        //获取合同信息
//        List<ContractVO> contractVOS = contractService.findContractByCaseId(caseId);
//        if(contractVOS.size()<contractSeq)
//            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
//        ContractVO contractVO = contractVOS.get(contractSeq-1);
//
//        return ResultUtil.success("success",getContractInformation(response,caseId,contractVO));
//    }

    @PostMapping("/{id}")
    @ApiOperation("推送合同")
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result pushContract(@PathVariable("id") Long contractId,@RequestParam Long caseId){
        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);
        if(ObjectUtils.isEmpty(step)||!step.getStatus().equals(StepEnum.PROCESS.getMsg()))
            throw new DescribeException(STEP_HAS_NOT_PROCESS);

        Long currentId = step.getUserId1();
        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
            throw new DescribeException(STEP_USER_NOT_EXPECTED);
        }

        Contract contract = contractService.findContractById(contractId);
        if(contract.getIsPush())
            throw new DescribeException(ExceptionEnum.CONTRACT_HAS_PUSH);

        contractService.updateIsPushById(contractId);

        //TODO:微信推送预审通过消息和通知下一环节
//        SysMessage message = new SysMessage();
//        message.setMobile(null);
//        message.setUserRole("");
//        message.setMessageTitle("");
//        message.setMessageContent("");
//        message.setStepName("");
//        message.setRelatedId(loanCase.getId());
//        message.setRelatedType("");
//        messageService.addMessage(message);
//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());


        return ResultUtil.success("success");
    }

    @GetMapping("/customer")
    @ApiOperation("显示所有合同详情（客户）")
    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
    public Result findContractsByCustomer(@RequestParam Long caseId) {

        return ResultUtil.success("success",contractService.findContractByCaseIdAndIsPush(caseId,true));
    }
    @GetMapping("/customer/{id}")
    @ApiOperation("显示合同文件详情（客户）")
    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
    public void findContractsDetailByCustomer(@PathVariable("id") Long contractId ,@RequestParam Long caseId,HttpServletResponse response){
        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
        //显示已经推送过的合同
        Contract contractById = contractService.findContractById(contractId);
        if(ObjectUtils.isEmpty(contractById))
            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);

        if (!contractById.getIsPush())
            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_PUSH);

        getContractInformation(response,caseId,BeanUtil.copyProperties(contractById,ContractVO.class));
    }

//    @GetMapping("/customer/{contractSeq}")
//    @ApiOperation("显示合同详情（客户）")
//    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
//    public Result findContractsByCustomer(@PathVariable("contractSeq") Integer contractSeq ,@RequestParam Long caseId,HttpServletResponse response){
//        //显示已经推送过的合同
//        List<ContractVO> contracts = contractService.findContractByCaseIdAndIsPush(caseId,true);
//        if(contracts.size()<contractSeq)
//            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
//        ContractVO contractVO = contracts.get(contractSeq-1);
//
//        return ResultUtil.success("success",getContractInformation(response,caseId,contractVO));
//    }
    //签署的电子信息先以附件上传
    //再修改合同状态
    @PostMapping("/{id}/sign")
    @ApiOperation("签署合同(客户)")
    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
    public Result updateContract(@PathVariable("id")Long contractId,@RequestParam Long signId,@RequestParam Long commitedId){
        Contract contract = contractService.findContractById(contractId);
        if(ObjectUtils.isEmpty(contract))
            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);

        if(!contract.getIsPush())
            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_PUSH);

        if(contract.getSignedByCustomer())
            throw new DescribeException(ExceptionEnum.CONTRACT_HAS_SIGNED);

        if(!contract.getCustomerId().equals(BaseContext.getCurrentId()))
            throw new DescribeException(ExceptionEnum.CONTRACT_SIGNED_PERMISSION_NOT_ALLOW);

        contractService.updateContractById1(contractId,commitedId,signId);

        return ResultUtil.success("success");
    }

    @PutMapping("/case/{caseId}")
    @ApiOperation("合同签订完成")
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result completeContract(@PathVariable("caseId")Long caseId){
        if(!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);
        if(ObjectUtils.isEmpty( step)||!step.getStatus().equals(StepEnum.PROCESS.getMsg()))
            throw new DescribeException(STEP_HAS_NOT_PROCESS);

        Long currentId = step.getUserId1();
        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
            throw new DescribeException(STEP_USER_NOT_EXPECTED);
        }

        //合同签约完成
        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.CONTRACT_SIGN_PARENT.getLabel(),caseId);
        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);

//        //出款开始环节
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.DISBURSE_PARENT.getLabel(),caseId);
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PLAN_REPORT.getLabel(),caseId);


//
//        //取证开始环节
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.COLLATERAL_RECEIVE.getLabel(),caseId);
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PLAN_SUBMISSION.getLabel(),caseId);
//
//        //送证开始环节
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.COLLATERAL_DELIVERY.getLabel(),caseId);
//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PLAN_SUBMISSION_2.getLabel(),caseId);

        return ResultUtil.success("success");
    }

    private void getContractInformation(HttpServletResponse response, Long caseId,ContractVO contractVO){
        LoanCaseSimpleVO loancase = loanService.findLoanCaseSimpleByIdAndIsDelete(caseId, false);
        CustomerVO customer = customerService.findByCustomerIdAndIsDelete(loancase.getCustomerId(),false);
        ContractInformation contractInformation = BeanUtil.copyProperties(customer, ContractInformation.class);
        contractInformation.setContractNo(contractVO.getContractNo());
        contractInformation.setInterestRate(contractVO.getInterestRate());

        String downloadName = contractVO.getContractName()+"-"+contractVO.getId();
        new PoiWordUtil().writeApprove(response,contractPath,contractInformation,downloadName);
    }

}
