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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.enums.DeptTypeEnum;
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.payment.*;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAPaymentDO;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOAPaymentService;
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.*;
import java.util.stream.Collectors;

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

/**
 * OA 付款申请 Controller
 *
 * @author 符溶馨

 */
@Tag(name = "管理后台 - OA 付款申请")
@RestController
@RequestMapping("/bpm/oa/payment")
@Validated
public class BpmOAPaymentController {

    @Resource
    private BpmOAPaymentService paymentService;

    @Resource
    private AdminUserApi userApi;

    @Resource
    private DeptApi deptApi;

    @PostMapping("/create")
    @Operation(summary = "创建付款申请")
    public CommonResult<Long> createPayment(@Valid @RequestBody BpmOAPaymentCreateReqVO createReqVO) {

        return success(paymentService.createPayment(getLoginUserId(), createReqVO));
    }

    @GetMapping("/get")
    @Operation(summary = "获得付款申请")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<BpmOAPaymentRespVO> getPayment(@RequestParam("id") Long id) {

        BpmOAPaymentDO payment = paymentService.getPayment(id);
        BpmOAPaymentRespVO respVO = paymentService.convertPayment(payment);

        return success(respVO);
    }

    @GetMapping("/getByProcessInstanceId")
    @Operation(summary = "获得付款申请")
    @Parameter(name = "BpmOAPaymentRespVO", description = "流程实例编号", required = true, example = "1024")
    public CommonResult<BpmOAPaymentRespVO> getByProcessInstanceId(@RequestParam("processInstanceId") String processInstanceId) {

        BpmOAPaymentDO payment = paymentService.getByProcessInstanceId(processInstanceId);
        BpmOAPaymentRespVO respVO = paymentService.convertPayment(payment);

        return success(respVO);
    }

    @GetMapping("/get-list")
    @Operation(summary = "获得指定条件的付款申请")
    @Parameter(name = "type", description = "付款类型", required = true, example = "1")
    public CommonResult<List<BpmOAPaymentRespVO>> getPayment(@RequestParam("type") Integer type) {

        List<BpmOAPaymentRespVO> list = paymentService.getPaymentList(type);

        return success(paymentService.getPaymentList(type));
    }

    @GetMapping("/page")
    @Operation(summary = "获得 后补票的付款申请分页列表")
    public CommonResult<PageResult<BpmOAPaymentRespVO>> getPage(@Valid BpmOAPaymentPageReqVO pageReqVO) {

        // 获取所有 财务部门信息
        List<DeptRespDTO> deptRespDTOS = deptApi.getDeptListByType(DeptTypeEnum.FINANCE_DEPT.getValue()).getCheckedData();
        // 筛选 所属总公司的财务部门
        List<DeptRespDTO> dto = deptApi.getDeptListByType(DeptTypeEnum.HEAD_COMPANY.getValue()).getCheckedData();
        Long headCompanyId = dto.get(0).getId();
        deptRespDTOS = deptRespDTOS.stream()
                .filter(item -> item.getFlag().contains(headCompanyId.toString()))
                .collect(Collectors.toList());

        // 获取财务部门下 所有用户信息
        List<AdminUserRespDTO> userRespDTOS = userApi.getUserListByDeptIds(convertSet(deptRespDTOS, DeptRespDTO::getId)).getCheckedData();
        List<Long> userIds = convertList(userRespDTOS, AdminUserRespDTO::getId);

        // 判断当前登录用户是否属于财务部
        pageReqVO.setIsMy(!userIds.contains(getLoginUserId()));

        PageResult<BpmOAPaymentRespVO> pageResult = BeanUtils.toBean(paymentService.getPaymentPage(pageReqVO, getLoginUserId()), BpmOAPaymentRespVO.class);
        if (CollUtil.isNotEmpty(pageResult.getList())) {

            // 获取发起人用户信息
            Set<Long> startUserIds = convertSet(pageResult.getList(), BpmOAPaymentRespVO::getUserId);
            Map<Long, AdminUserRespDTO> userMap = userApi.getUserMap(startUserIds);

            // 获取部门信息Map
            List<Long> deptIds = new ArrayList<>();
            // 获取工厂详情
            List<List<FactoryDetailVO>> factoryDetailList = convertList(pageResult.getList(), BpmOAPaymentRespVO::getFactoryDetail);
            List<FactoryDetailVO> factoryDetailVOS = factoryDetailList.stream().flatMap(List::stream).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(factoryDetailVOS)) {
                deptIds.addAll(convertList(factoryDetailVOS, FactoryDetailVO::getDeptId));
            }else {
                deptIds.addAll(convertList(pageResult.getList(), BpmOAPaymentRespVO::getDeptId));
            }
            // 添加公司集合
            deptIds.addAll(convertList(pageResult.getList(), BpmOAPaymentRespVO::getPaymentCompany));
            Map<Long, DeptRespDTO> dtoMap = deptApi.getDeptMap(new HashSet<>(deptIds));

            pageResult.getList().forEach(item -> {
                item.setUserName(userMap.get(item.getUserId()).getNickname());
                // 设置部门名称
                item.setDeptName(dtoMap.get(item.getDeptId()) != null ? dtoMap.get(item.getDeptId()).getName() : null);
                // 设置付款公司名称
                item.setPaymentCompanyName(dtoMap.get(item.getPaymentCompany()).getName());
                // 设置工厂名称
                item.getFactoryDetail().forEach(detail -> {
                    detail.setFactoryName(dtoMap.get(detail.getDeptId()).getName());
                });
            });
        }

        return success(pageResult);
    }

    @PutMapping("update-files")
    @Operation(summary = "继续上传附件")
    public CommonResult<Boolean> updateFiles(@Valid @RequestBody BpmOAPaymentUpdateReqVO updateReqVO) {
        paymentService.updateFiles(updateReqVO);
        return success(true);
    }

    @PutMapping("update-status")
    @Operation(summary = "修改付款申请的补票状态")
    public CommonResult<Boolean> updateStatus(@Valid @RequestBody BpmOAPaymentUpdateReqVO updateReqVO) {
        paymentService.updateStatus(updateReqVO);
        return success(true);
    }

    @PutMapping("/delete-files")
    @Operation(summary = "删除后补附件")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @Parameter(name = "url", description = "url", required = true, example = "1024")
    public CommonResult<Boolean> deleteUser(@RequestParam("id") Long id,
                                            @RequestParam("url") String url) {
        paymentService.deleteFiles(id, url);
        return success(true);
    }
}