package com.loan.system.controller.wechat;

import com.loan.system.context.BaseContext;
import com.loan.system.domain.dto.*;
import com.loan.system.domain.entity.ApprovalRecord;
import com.loan.system.domain.entity.Disbursement;
import com.loan.system.domain.entity.Repayment;
import com.loan.system.domain.entity.RepaymentRecord;
import com.loan.system.domain.enums.*;
import com.loan.system.domain.pojo.Result;
import com.loan.system.domain.vo.*;
import com.loan.system.exception.DescribeException;
import com.loan.system.service.*;
import com.loan.system.service.DisbursementRecordService;
import com.loan.system.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.bytebuddy.dynamic.scaffold.MethodRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static com.loan.system.domain.enums.ExceptionEnum.*;

@RestController
@RequestMapping("/wechat/repayment")
@Api(tags = "还款接口")
public class RepaymentController {

    @Autowired
    private DisbursementService disbursementService;
    @Autowired
    private StepService stepService;
    @Autowired
    private DisbursementRecordService disbursementRecordService;
    @Autowired
    private RepaymentService repaymentService;
    @Autowired
    private RepaymentRecordService repaymentRecordService;
    @Autowired
    private LoanService loanService;

    @GetMapping("/{caseId}/repayDetails")
    @ApiOperation("显示回款详情")//与loanContraller的方法一致，但为了规范
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result findLoanCaseDetails(@PathVariable("caseId")Long caseId){
        if(!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
        RepaymentDetailVO repaymentDetailVO = new RepaymentDetailVO();
        repaymentDetailVO.setCustomer(disbursementDetailVO.getCustomer());
        repaymentDetailVO.setLoanCase(disbursementDetailVO.getLoanCase());

        //填充
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
        Double currentAmount= 0.0;
        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
            if(!repaymentRecordVO.getIsInterest())//审批、财务环节显示审批通过后的总额
                currentAmount += repaymentRecordVO.getAmount();

        repaymentDetailVO.setRepaymentRecords(repaymentRecordVOS);
        repaymentDetailVO.setCurrentAmount(currentAmount);
        repaymentDetailVO.setTotalAmount(repayment.getTotalAmount());
        //财务核算后
        repaymentDetailVO.setInterests(repayment.getInterest());
        //余额回款
        repaymentDetailVO.setWay(repayment.getRepayWay());

        return ResultUtil.success("success",repaymentDetailVO);
    }


    @PostMapping
    @ApiOperation(value = "启动回款")
    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
    public Result addDisbursement(@RequestBody RepaymentRecordDTO repaymentRecordDTO, @RequestParam Long caseId, @RequestParam Long recordId) {
        if(ObjectUtils.isEmpty(repaymentRecordDTO))
            throw new DescribeException(INPUT_ERROR);

        if(caseId == null ||!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

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

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

        //最新回款记录还在审批中，则不能回款
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);

        //上报计划
        if(recordId == -1){
            //审批意见为驳回，无法新增
            if(repaymentRecordVOS.get(repaymentRecordVOS.size()-1).getApprovalDecision().equals(DecisionEnum.REJECT.getMsg()))
                throw new DescribeException(DISBURSEMENT_HAS_NOT_COMPLETED);
            repaymentRecordService.addRepaymentRecord(repaymentRecordDTO,repayment.getId());
        } else{
            //审批意见为通过，无法修改
            if(repaymentRecordVOS.get(repaymentRecordVOS.size()-1).getApprovalDecision().equals(DecisionEnum.PASS.getMsg()))
                throw new DescribeException(DISBURSEMENT_HAS_COMPLETED);
            repaymentRecordService.updateRepaymentRecordById(repaymentRecordDTO,recordId);
        }
        // DisbursementVO disbursementVO = disbursementService.addDisbursement(disbursementDTO);

        //修改状态
        if(isCleared(caseId)){//若结清，则回款完成
            repaymentService.updateIsClearedByCaseId(true,caseId);
            stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.REPAY_START.getLabel(), caseId);
        }
        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);

        //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("/{caseId}/appravalDetails")
    @ApiOperation("显示审批详情")//与loanContraller的方法一致，但为了规范
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result findLoanCaseDetails2(@PathVariable("caseId")Long caseId){
        return ResultUtil.success("success",getDetails(caseId));
    }

    //TODO:在回款记录添加审批记录，且每次审批完之后才能再回款
    @PostMapping("/approval/pass")
    @ApiOperation(value = "回款审批")
    @PreAuthorize("@pms.hasRole('APPROVER')")
    public Result repaymentApproval(@RequestBody ApprovalDTO approvalDTO) {
        if(ObjectUtils.isEmpty(approvalDTO)||approvalDTO.getCaseId() == null)
            throw new DescribeException(INPUT_ERROR);

        if(!loanService.existsByIdAndIsDelete(approvalDTO.getCaseId()))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

        Long caseId = approvalDTO.getCaseId();

        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);
        if(!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
            throw new DescribeException(STEP_HAS_NOT_PROCESS);

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

        //填写审批意见
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        repaymentRecordService.updateApprovalById(approvalDTO.getComments(),DecisionEnum.REJECT.getMsg(),repayment.getId());

        //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());

        //修改出款单
        repaymentService.updateApprovalUserByCaseId(BaseContext.getCurrentId(),caseId);

        //修改状态
        stepService.updateUserByCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(), BaseContext.getCurrentId(), caseId);
        if(isCleared(caseId))
            stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.REPAY_APPROVAL.getLabel(), caseId);
        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(), StepPropertyEnum.FINANCE_CHECK.getLabel(),caseId);

        return ResultUtil.success("success");
    }

    @PostMapping("/approval/reject")
    @ApiOperation(value = "回款审批驳回")
    @PreAuthorize("@pms.hasRole('APPROVER')")
    public Result repaymentCancel(@RequestBody ApprovalDTO approvalDTO) {
        if(ObjectUtils.isEmpty(approvalDTO)||approvalDTO.getCaseId() == null)
            throw new DescribeException(INPUT_ERROR);

        if(!loanService.existsByIdAndIsDelete(approvalDTO.getCaseId()))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

        Long caseId = approvalDTO.getCaseId();
        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_START.getLabel(), caseId);
        if(step.getStatus().equals(StepEnum.PROCESS.getMsg()))
            throw new DescribeException(PRE_STEP_NOT_COMPLETE);

        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);
        if(stepVO.getStatus().equals(StepEnum.COMPLETED.getMsg()))
            throw new DescribeException(ExceptionEnum.STEP_HAS_COMPLETEED);

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

        //填写驳回意见
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        repaymentRecordService.updateApprovalById(approvalDTO.getComments(),DecisionEnum.REJECT.getMsg(),repayment.getId());

        //修改出款单
        repaymentService.updateApprovalUserByCaseId(BaseContext.getCurrentId(),caseId);

        //修改负责人
        stepService.updateUserByCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(), BaseContext.getCurrentId(), caseId);
        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(), StepPropertyEnum.REPAY_START.getLabel(),  caseId);
        stepService.updateStatusByCaseId(StepEnum.UNSTART.getMsg(), StepPropertyEnum.REPAY_APPROVAL.getLabel(), caseId);

        //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("/financeDetails")
    @ApiOperation("显示财务核算详情")//与loanContraller的方法一致，但为了规范
    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
    public Result findLoanCaseDetails3(@RequestParam Long caseId){
        if(caseId==null)
            throw new DescribeException(INPUT_ERROR);
        return ResultUtil.success("success",getDetails(caseId));
    }

    @PostMapping("/financeCheck")
    @ApiOperation(value = "财务核算")
    @PreAuthorize("@pms.hasRole('FINANCE')")
    public Result financeDisbursement( @RequestParam Long caseId,@RequestParam Double interest) {
        if(caseId==null||!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

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

        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        if(!repayment.getIsCleared())
            throw new DescribeException(FUND_NOT_CLEAR);

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

        //修改回款单
        repaymentService.updateIntersetsByCaseId(interest,caseId);

        //修改状态
        stepService.updateUserByCaseId(StepPropertyEnum.FINANCE_CHECK.getLabel(), BaseContext.getCurrentId(), caseId);
        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.FINANCE_CHECK.getLabel(),caseId);
        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.BALANCE_REPAY.getLabel(), caseId);

        //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");
    }

    private Boolean isCleared(Long caseId){
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        //获取回款记录
        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);

        Double currentAmount= 0.0;
        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
            currentAmount += repaymentRecordVO.getAmount();

        Double totalAmount = repaymentService.findByCaseIdAndIsDelete(caseId, false).getTotalAmount();

        return (totalAmount-currentAmount)< Double.MIN_VALUE;

    }

    @PostMapping("/balanceRepay")
    @ApiOperation(value = "费息回款")
    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
    public Result balanceRepay(@RequestParam Long caseId , @RequestBody RepaymentRecordDTO repaymentRecordDTO , @RequestParam String way) {
        if(ObjectUtils.isEmpty(repaymentRecordDTO)||caseId==null)
            throw new DescribeException(INPUT_ERROR);
        if(!loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

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

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

        repaymentService.updateRepayWayByCaseId(way,caseId);
        //添加回款记录
        repaymentRecordDTO.setIsInterest( true);
        repaymentRecordService.addRepaymentRecord(repaymentRecordDTO, repaymentService.findByCaseIdAndIsDelete(caseId, false).getId());

        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.BALANCE_REPAY.getLabel(), BaseContext.getCurrentId(), caseId);
        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.BALANCE_REPAY.getLabel(),caseId);
        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.FINANCE_CONFIRM.getLabel(), caseId);

        //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");
    }

    @PostMapping("/financeConfirm")
    @ApiOperation(value = "财务确认")
    @PreAuthorize("@pms.hasRole('FINANCE')")
    public Result financeConfirm(@RequestParam Long caseId) {
        if(caseId==null || !loanService.existsByIdAndIsDelete(caseId))
            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);

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

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

        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.FINANCE_CONFIRM.getLabel(), BaseContext.getCurrentId(), caseId);
        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.FINANCE_CONFIRM.getLabel(),caseId);

        //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");
    }

    private RepaymentDetailVO getDetails(Long caseId){
        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
        RepaymentDetailVO repaymentDetailVO = new RepaymentDetailVO();
        repaymentDetailVO.setCustomer(disbursementDetailVO.getCustomer());
        repaymentDetailVO.setLoanCase(disbursementDetailVO.getLoanCase());

        //填充
        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
        Double currentAmount= 0.0;
        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
            if(repaymentRecordVO.getApprovalDecision().equals(DecisionEnum.PASS.getMsg())&& !repaymentRecordVO.getIsInterest())//审批、财务环节显示审批通过后的总额
                currentAmount += repaymentRecordVO.getAmount();

        repaymentDetailVO.setRepaymentRecords(repaymentRecordVOS);
        repaymentDetailVO.setCurrentAmount(currentAmount);
        repaymentDetailVO.setTotalAmount(repayment.getTotalAmount());
        //财务核算后
        repaymentDetailVO.setInterests(repayment.getInterest());
        //余额回款
        repaymentDetailVO.setWay(repayment.getRepayWay());

        return repaymentDetailVO;
    }

}
