package cn.iocoder.yudao.module.bpm.controller.admin.oa;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOALoanRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.loan.BpmOAReturnVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.financialpayment.FinancialPaymentDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALoanDO;
import cn.iocoder.yudao.module.bpm.service.financialpayment.FinancialPaymentService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALoanService;
import cn.iocoder.yudao.module.smartfactory.api.factoryInfo.FactoryInfoApi;
import cn.iocoder.yudao.module.smartfactory.api.factoryInfo.dto.FactoryInfoDTO;
import cn.iocoder.yudao.module.smartfactory.api.staff.StaffApi;
import cn.iocoder.yudao.module.smartfactory.api.staff.dto.StaffDTO;
import cn.iocoder.yudao.module.system.api.bank.BankApi;
import cn.iocoder.yudao.module.system.api.bank.dto.BankRespDTO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

import java.util.List;
import java.util.Map;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * OA 借支申请 Controller
 *
 * @author 符溶馨
 */
@Tag(name = "管理后台 - OA 借支申请")
@RestController
@RequestMapping("/bpm/oa/loan")
@Validated
public class BpmOALoanController {

    @Resource
    private BpmOALoanService loanService;

    @Resource
    private BankApi bankApi;

    @Resource
    private DeptApi deptApi;

    @Resource
    private AdminUserApi userApi;

    @Resource
    private StaffApi staffApi;

    @Resource
    private FactoryInfoApi factoryInfoApi;

    @Resource
    private FinancialPaymentService financialPaymentService;

    @PostMapping("/create")
    @Operation(summary = "创建借支申请")
    public CommonResult<Long> createLoan(@Valid @RequestBody BpmOALoanCreateReqVO createReqVO) {

        return success(loanService.createLoan(getLoginUserId(), createReqVO));
    }

    @GetMapping("/get")
    @Operation(summary = "获得借支申请")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<BpmOALoanRespVO> getLoan(@RequestParam("id") Long id) {
        BpmOALoanDO loan = loanService.getLoan(id);
        BpmOALoanRespVO respVO = BeanUtils.toBean(loan, BpmOALoanRespVO.class);

        if (respVO != null) {
            // 获取银行卡信息
            BankRespDTO bankRespDTO = null;
            if (loan.getBankId() != null) {
                bankRespDTO = bankApi.getBank(loan.getBankId()).getCheckedData();
                if (bankRespDTO != null) {
                    respVO.setBankNo(bankRespDTO.getBankNo());
                    respVO.setBankName(bankRespDTO.getBankName());
                    respVO.setPayeeName(bankRespDTO.getNickname());
                }
            }

            // 获取工厂信息
            DeptRespDTO dto = deptApi.getDeptByFactoryId(loan.getFactoryId()).getCheckedData();
            // 设置工厂名称
            respVO.setFactoryName(dto != null ? dto.getName() : null);

            // 获取用户信息
            StaffDTO staffDTO = staffApi.getStaff(loan.getSfUserId()).getCheckedData();
            //设置员工名称
            respVO.setSfUserName(staffDTO != null ? staffDTO.getNickName() : null);
        }

        return success(respVO);
    }

    @GetMapping("/getByProcessInstanceId")
    @Operation(summary = "获得借支申请")
    @Parameter(name = "processInstanceId", description = "流程实例编号", required = true, example = "1024")
    public CommonResult<BpmOALoanRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {
        BpmOALoanDO loan = loanService.getByProcessInstanceId(processInstanceId);
        BpmOALoanRespVO respVO = BeanUtils.toBean(loan, BpmOALoanRespVO.class);

        if (respVO != null) {
            // 获取银行卡信息
            BankRespDTO bankRespDTO = null;
            if (loan.getBankId() != null) {
                bankRespDTO = bankApi.getBank(loan.getBankId()).getCheckedData();
                if (bankRespDTO != null) {
                    respVO.setBankNo(bankRespDTO.getBankNo());
                    respVO.setBankName(bankRespDTO.getBankName());
                    respVO.setPayeeName(bankRespDTO.getNickname());
                }
            }

            // 获取工厂信息
            DeptRespDTO dto = deptApi.getDeptByFactoryId(loan.getFactoryId()).getCheckedData();
            // 设置工厂名称
            respVO.setFactoryName(dto != null ? dto.getName() : null);

            // 获取用户信息
            StaffDTO staffDTO = staffApi.getStaff(loan.getSfUserId()).getCheckedData();
            //设置员工名称
            respVO.setSfUserName(staffDTO != null ? staffDTO.getNickName() : null);
        }

        return success(respVO);
    }

    @GetMapping("/get-list")
    @Operation(summary = "获得指定用户的借支申请列表")
    public CommonResult<PageResult<BpmOALoanRespVO>> getLoanList(BpmOALoanPageReqVO pageReqVO) {

        PageResult<BpmOALoanDO> loanList = loanService.getListByStaffId(pageReqVO);
        PageResult<BpmOALoanRespVO> respVOS = BeanUtils.toBean(loanList, BpmOALoanRespVO.class);
        if (CollUtil.isNotEmpty(respVOS.getList())) {

            // 获取支付信息
            List<String> processInstanceIds = convertList(loanList.getList(), BpmOALoanDO::getProcessInstanceId);
            Map<String, FinancialPaymentDO> financialPayments = convertMap(financialPaymentService.getFinancialPaymentList(processInstanceIds), FinancialPaymentDO::getProcessInstanceId);

            // 获取申请人信息
            Set<Long> userIds = convertSet(loanList.getList(), BpmOALoanDO::getUserId);
            Map<Long, AdminUserRespDTO> userMap = userApi.getUserMap(userIds);

            // 获取借支人信息
            Set<Long> loanUserIds = convertSet(loanList.getList(), BpmOALoanDO::getSfUserId);
            Map<Long, StaffDTO> loanUserMap = convertMap(staffApi.getStaffList(loanUserIds).getCheckedData(), StaffDTO::getId);

            // 获取工厂信息
            Set<Long> deptIds = convertSet(loanList.getList(), BpmOALoanDO::getFactoryId);
            Map<Long, FactoryInfoDTO> factoryMap = factoryInfoApi.getFactoryMap(deptIds);

            respVOS.getList().forEach(item -> {
                // 设置申请人名称
                item.setUserName(userMap.get(item.getUserId()).getNickname());
                // 设置借支用户名称
                item.setSfUserName(loanUserMap.get(item.getSfUserId()).getNickName());
                // 设置借支用户部门名称
                item.setFactoryName(factoryMap.get(item.getFactoryId()).getName());
                // 设置支付状态
                item.setStatus(financialPayments.containsKey(item.getProcessInstanceId()) ? financialPayments.get(item.getProcessInstanceId()).getStatus() : 2);
            });
        }

        return success(respVOS);
    }

    @GetMapping("/get-return-list")
    @Operation(summary = "获得指定用户的还款列表")
    public CommonResult<PageResult<BpmOAReturnVO>> getReturnList(BpmOALoanPageReqVO pageReqVO) {

        PageResult<BpmOAReturnVO> respVOS = loanService.getReturnList(pageReqVO);

        return success(respVOS);
    }
}
