package cn.iocoder.yudao.module.asset.controller.admin.assetreceiveinfo;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.asset.controller.admin.assetreceiveinfo.vo.AssetReceiveInfoPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetreceiveinfo.vo.AssetReceiveInfoRespVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetreceiveinfo.vo.AssetReceiveInfoSaveReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.assetreceiveinfo.vo.AssetReceiveInfoUpdateReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.assetreceiveinfo.AssetReceiveInfoDO;
import cn.iocoder.yudao.module.asset.enums.AssetReturnStateEnum;
import cn.iocoder.yudao.module.asset.service.assetreceiveinfo.AssetReceiveInfoService;
import cn.iocoder.yudao.module.employee.api.EmployeeApi;
import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.PostApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 固定资产领用、归还信息")
@RestController
@RequestMapping("/finance/asset/receive-info")
@Validated
public class AssetReceiveInfoController {

    @Resource
    private AssetReceiveInfoService receiveInfoService;

    @Resource
    private EmployeeApi employeeApi;

    @Resource
    private DeptApi deptApi;

    @Resource
    private PostApi postApi;

    @PostMapping("/create")
    @Operation(summary = "领用固定资产")
    @ApiOperationSupport(order = 1)
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:create')")
    public CommonResult<Long> createReceiveInfo(@Valid @RequestBody AssetReceiveInfoSaveReqVO createReqVO) {
        return success(receiveInfoService.createReceiveInfo(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "归还固定资产")
    @ApiOperationSupport(order = 2)
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:update')")
    public CommonResult<Boolean> updateReceiveInfo(@Valid @RequestBody AssetReceiveInfoUpdateReqVO updateReqVO) {
        receiveInfoService.updateReceiveInfo(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除固定资产领用信息")
    @ApiOperationSupport(order = 4)
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:delete')")
    public CommonResult<Boolean> deleteReceiveInfo(@RequestParam("id") Long id) {
        receiveInfoService.deleteReceiveInfo(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得固定资产领用信息")
    @ApiOperationSupport(order = 5)
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:query')")
    public CommonResult<AssetReceiveInfoRespVO> getReceiveInfo(@RequestParam("id") Long id) {
        AssetReceiveInfoDO receiveInfo = receiveInfoService.getReceiveInfo(id);
        return success(BeanUtils.toBean(receiveInfo, AssetReceiveInfoRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得固定资产流转分页信息")
    @ApiOperationSupport(order = 3)
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:query')")
    public CommonResult<PageResult<AssetReceiveInfoRespVO>> getReceiveInfoPage(@Valid @ParameterObject AssetReceiveInfoPageReqVO pageReqVO) {
        PageResult<AssetReceiveInfoDO> pageResult = receiveInfoService.getReceiveInfoPage(pageReqVO);
        PageResult<AssetReceiveInfoRespVO> voPageResult = BeanUtils.toBean(pageResult, AssetReceiveInfoRespVO.class);
        List<AssetReceiveInfoRespVO> list = voPageResult.getList();

        // 领用人信息
        Set<Long> employeeIdSet = list.stream().map(AssetReceiveInfoRespVO::getEmployeeId).collect(Collectors.toSet());
        List<EmployeeRespDTO> employeeRespDTOList = employeeApi.getEmployeeListByIds(employeeIdSet);
        Map<Long, EmployeeRespDTO> employeeMap = CollectionUtils.convertMap(employeeRespDTOList, EmployeeRespDTO::getId);
        // 领用人部门信息
        Set<Long> deptIdSet = list.stream().map(AssetReceiveInfoRespVO::getDeptId).collect(Collectors.toSet());
        List<DeptRespDTO> deptList = deptApi.getDeptList(deptIdSet);
        Map<Long, DeptRespDTO> deptMap = CollectionUtils.convertMap(deptList, DeptRespDTO::getId);
        // 领用人职位信息
        Set<Long> postIdSet = list.stream().map(AssetReceiveInfoRespVO::getPostId).collect(Collectors.toSet());
        List<PostRespDTO> postList = postApi.getPostList(postIdSet);
        Map<Long, PostRespDTO> postMap = CollectionUtils.convertMap(postList, PostRespDTO::getId);
        // 操作人
        Set<Long> updaterIdSet = list.stream().map(AssetReceiveInfoRespVO::getUpdater).collect(Collectors.toSet());
        List<EmployeeRespDTO> updaterList = employeeApi.getEmployeeListByIds(updaterIdSet);
        Map<Long, EmployeeRespDTO> updaterMap = CollectionUtils.convertMap(updaterList, EmployeeRespDTO::getId);
        // 是否归还
        Map<Integer, String> returnStateMap = Arrays.stream(AssetReturnStateEnum.values()).collect(Collectors.toMap(AssetReturnStateEnum::getState, AssetReturnStateEnum::getDesc));

        for (AssetReceiveInfoRespVO assetReceiveInfoRespVO : list) {
            EmployeeRespDTO employeeRespDTO = employeeMap.get(assetReceiveInfoRespVO.getEmployeeId());
            if (employeeRespDTO != null) {
                assetReceiveInfoRespVO.setEmployeeName(employeeRespDTO.getName());
                assetReceiveInfoRespVO.setEmployeePhone(employeeRespDTO.getPhone());
            }
            DeptRespDTO deptRespDTO = deptMap.get(assetReceiveInfoRespVO.getDeptId());
            if (deptRespDTO != null) {
                assetReceiveInfoRespVO.setDeptName(deptRespDTO.getName());
            }
            PostRespDTO postRespDTO = postMap.get(assetReceiveInfoRespVO.getPostId());
            if (postRespDTO != null) {
                assetReceiveInfoRespVO.setPosition(postRespDTO.getName());
            }
            EmployeeRespDTO updaterRespDTO = updaterMap.get(assetReceiveInfoRespVO.getUpdater());
            if (updaterRespDTO != null) {
                assetReceiveInfoRespVO.setOperatorName(updaterRespDTO.getName());
            }
            String returnStateDesc = returnStateMap.getOrDefault(assetReceiveInfoRespVO.getReturned(), "未知");
            assetReceiveInfoRespVO.setReturnedDesc(returnStateDesc);
        }
        return success(voPageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出固定资产领用信息 Excel")
    @ApiOperationSupport(order = 6)
    // @PreAuthorize("@ss.hasPermission('asset:receive-info:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportReceiveInfoExcel(@Valid AssetReceiveInfoPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<AssetReceiveInfoDO> list = receiveInfoService.getReceiveInfoPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "固定资产领用信息.xls", "数据", AssetReceiveInfoRespVO.class,
                        BeanUtils.toBean(list, AssetReceiveInfoRespVO.class));
    }

}