package cn.iocoder.yudao.module.bpm.controller.admin.meeting.reserve;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
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.bpm.api.metting.room.vo.OaMeetingRoomRespDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.meeting.reserve.vo.OaMeetingReservePageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.meeting.reserve.vo.OaMeetingReserveRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.meeting.reserve.vo.OaMeetingReserveSaveReqVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.meeting.reserve.OaMeetingReserveDO;
import cn.iocoder.yudao.module.bpm.enums.MeetingReserveStatusEnum;
import cn.iocoder.yudao.module.bpm.service.meeting.reserve.OaMeetingReserveService;
import cn.iocoder.yudao.module.bpm.service.meeting.room.OaMeetingRoomService;
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.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.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.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
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("/bpm/oa-meeting-reserve")
@Validated
public class OaMeetingReserveController {

    @Resource
    private OaMeetingReserveService oaMeetingReserveService;

    @Resource
    private EmployeeApi employeeApi;

    @Resource
    private DeptApi deptApi;

    @Resource
    private OaMeetingRoomService oaMeetingRoomService;

    @PostMapping("/create")
    @Operation(summary = "创建会议室预定管理信息")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:create')")
    public CommonResult<Long> createOaMeetingReserve(@Valid @RequestBody OaMeetingReserveSaveReqVO createReqVO) {
        return success(oaMeetingReserveService.createOaMeetingReserve(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新会议室预定管理信息")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:update')")
    public CommonResult<Boolean> updateOaMeetingReserve(@Valid @RequestBody OaMeetingReserveSaveReqVO updateReqVO) {
        oaMeetingReserveService.updateOaMeetingReserve(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除会议室预定管理信息")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:delete')")
    public CommonResult<Boolean> deleteOaMeetingReserve(@RequestParam("id") Long id) {
        oaMeetingReserveService.deleteOaMeetingReserve(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得会议室预定管理信息")
    @Parameter(name = "id", description = "编号", required = true, example = "2")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:query')")
    public CommonResult<OaMeetingReserveRespVO> getOaMeetingReserve(@RequestParam("id") Long id) {
        OaMeetingReserveDO oaMeetingReserve = oaMeetingReserveService.getOaMeetingReserve(id);
        OaMeetingReserveRespVO oaMeetingReserveRespVO = BeanUtils.toBean(oaMeetingReserve, OaMeetingReserveRespVO.class);
        String participants = oaMeetingReserve.getParticipants();
        if (StrUtil.isNotBlank(participants)) {
            String[] participantsStringArray = participants.split(",");
            List<Long> participantsLongList = Arrays.stream(participantsStringArray).map(Long::valueOf).collect(Collectors.toList());
            oaMeetingReserveRespVO.setParticipants(participantsLongList);

            List<EmployeeRespDTO> employeeRespDTOList = employeeApi.getEmployeeListByIds(participantsLongList);
            String participantsName = employeeRespDTOList.stream().map(EmployeeRespDTO::getName).collect(Collectors.joining(","));
            oaMeetingReserveRespVO.setParticipantsName(participantsName);
        } else {
            oaMeetingReserveRespVO.setParticipants(Collections.emptyList());
        }
        // 申请人
        Long applyEmployeeId = oaMeetingReserve.getApplyEmployeeId();
        if (applyEmployeeId != null) {
            EmployeeRespDTO employeeRespDTO = employeeApi.getEmployeeById(applyEmployeeId);
            oaMeetingReserveRespVO.setApplyEmployeeName(employeeRespDTO.getName());
        }
        // 状态描述
        String status = oaMeetingReserve.getStatus();
        Map<String, String> enumsMap = Arrays.stream(MeetingReserveStatusEnum.values())
                .collect(Collectors.toMap(MeetingReserveStatusEnum::getStatus, MeetingReserveStatusEnum::getDesc));
        oaMeetingReserveRespVO.setStatusDesc(enumsMap.get(status));
        // 部门名称
        Long deptId = oaMeetingReserve.getDeptId();
        if (deptId != null) {
            DeptRespDTO dept = deptApi.getDept(deptId);
            if (dept != null) {
                oaMeetingReserveRespVO.setDepName(dept.getName());
            }
        }

        return success(oaMeetingReserveRespVO);
    }

    @GetMapping("/page")
    @Operation(summary = "获得会议室预定管理信息分页")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:query')")
    public CommonResult<PageResult<OaMeetingReserveRespVO>> getOaMeetingReservePage(@Valid @ParameterObject OaMeetingReservePageReqVO pageReqVO) {
        PageResult<OaMeetingReserveDO> pageResult = oaMeetingReserveService.getOaMeetingReservePage(pageReqVO);
        // List<OaMeetingReserveDO> oaMeetingReserveDOList = pageResult.getList();
        PageResult<OaMeetingReserveRespVO> voPageResult = BeanUtils.toBean(pageResult, OaMeetingReserveRespVO.class);
        List<OaMeetingReserveRespVO> oaMeetingReserveRespVOList = voPageResult.getList();
        if (oaMeetingReserveRespVOList.size() > 0) {
            // 申请人
            List<Long> applyEmployeeIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getApplyEmployeeId).collect(Collectors.toList());
            List<EmployeeRespDTO> employeeRespDTOList = employeeApi.getEmployeeListByIds(applyEmployeeIds);
            Map<Long, EmployeeRespDTO> employeeRespDTOMap = CollectionUtils.convertMap(employeeRespDTOList, EmployeeRespDTO::getId, Function.identity());

            // // 参与人
            // List<Long> participantEmployeeIds = new ArrayList<>();
            // for (OaMeetingReserveDO oaMeetingReserveDO : oaMeetingReserveDOList) {
            //     String participants = oaMeetingReserveDO.getParticipants();
            //     if (StrUtil.isNotBlank(participants)) {
            //         String[] participantsStringArray = participants.split(",");
            //         List<Long> participantsLongList = Arrays.stream(participantsStringArray).map(Long::valueOf).collect(Collectors.toList());
            //         participantEmployeeIds.addAll(participantsLongList);
            //     }
            // }
            // List<AdminUserRespDTO> participantUserList = adminUserApi.getUserList(participantEmployeeIds);
            // Map<Long, AdminUserRespDTO> participantUserMap = participantUserList.stream().collect(Collectors.toMap(AdminUserRespDTO::getId, Function.identity()));

            // 状态描述
            Map<String, String> enumsMap = Arrays.stream(MeetingReserveStatusEnum.values())
                    .collect(Collectors.toMap(MeetingReserveStatusEnum::getStatus, MeetingReserveStatusEnum::getDesc));

            // 部门名称
            List<Long> deptIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getDeptId).collect(Collectors.toList());
            List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
            Map<Long, DeptRespDTO> deptMap = deptList.stream().collect(Collectors.toMap(DeptRespDTO::getId, Function.identity()));

            // 会议室名称
            List<Long> roomIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getRoomId).collect(Collectors.toList());
            List<OaMeetingRoomRespDTO> roomList = oaMeetingRoomService.getOaMeetingRoomList(roomIds);
            Map<Long, OaMeetingRoomRespDTO> roomRespDTOMap = roomList.stream().collect(Collectors.toMap(OaMeetingRoomRespDTO::getId, Function.identity()));

            for (OaMeetingReserveRespVO oaMeetingReserveRespVO : oaMeetingReserveRespVOList) {
                // 申请人姓名
                Long applyEmployeeId = oaMeetingReserveRespVO.getApplyEmployeeId();
                if (applyEmployeeId != null) {
                    EmployeeRespDTO employeeRespDTO = employeeRespDTOMap.get(applyEmployeeId);
                    if (employeeRespDTO != null) {
                        oaMeetingReserveRespVO.setApplyEmployeeName(employeeRespDTO.getName());
                    }
                }
                // // 参与人姓名
                // String participants = oaMeetingReserveRespVO.getParticipants();
                // 状态描述
                String status = oaMeetingReserveRespVO.getStatus();
                oaMeetingReserveRespVO.setStatusDesc(enumsMap.get(status));
                // 部门名称
                Long deptId = oaMeetingReserveRespVO.getDeptId();
                if (deptId != null) {
                    DeptRespDTO dept = deptMap.get(deptId);
                    if (dept != null) {
                        oaMeetingReserveRespVO.setDepName(dept.getName());
                    }
                }
                // 会议室名称
                Long roomId = oaMeetingReserveRespVO.getRoomId();
                if (roomId != null) {
                    OaMeetingRoomRespDTO room = roomRespDTOMap.get(roomId);
                    if (room != null) {
                        oaMeetingReserveRespVO.setRoomName(room.getName());
                    }
                }
            }
        }

        return success(voPageResult);
    }

    @GetMapping("/list")
    @Operation(summary = "获得会议室预定管理信息列表")
    @Parameter(name = "roomId", description = "会议室id", required = false, example = "2")
    @Parameter(name = "month", description = "年月，格式：yyyy-MM", required = true, example = "2024-07")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:list')")
    public CommonResult<List<OaMeetingReserveRespVO>> getOaMeetingReserveList(@RequestParam(value = "roomId", required = false) Long roomId, @RequestParam("month") String month) throws ParseException {
        List<OaMeetingReserveDO> doList = oaMeetingReserveService.getOaMeetingReserveList(roomId, month);
        List<OaMeetingReserveRespVO> voList = BeanUtils.toBean(doList, OaMeetingReserveRespVO.class);
        if (CollUtil.isNotEmpty(voList)) {
            // 状态描述
            Map<String, String> enumsMap = Arrays.stream(MeetingReserveStatusEnum.values())
                    .collect(Collectors.toMap(MeetingReserveStatusEnum::getStatus, MeetingReserveStatusEnum::getDesc));
            for (OaMeetingReserveRespVO oaMeetingReserveRespVO : voList) {
                String status = oaMeetingReserveRespVO.getStatus();
                oaMeetingReserveRespVO.setStatusDesc(enumsMap.get(status));
            }
        }
        return success(voList);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出会议室预定管理信息 Excel")
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportOaMeetingReserveExcel(@Valid OaMeetingReservePageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OaMeetingReserveDO> list = oaMeetingReserveService.getOaMeetingReservePage(pageReqVO).getList();
        List<OaMeetingReserveRespVO> oaMeetingReserveRespVOList = BeanUtils.toBean(list, OaMeetingReserveRespVO.class);
        if (oaMeetingReserveRespVOList.size() > 0) {
            // 申请人
            List<Long> applyEmployeeIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getApplyEmployeeId).collect(Collectors.toList());
            List<EmployeeRespDTO> employeeRespDTOList = employeeApi.getEmployeeListByIds(applyEmployeeIds);
            Map<Long, EmployeeRespDTO> employeeRespDTOMap = CollectionUtils.convertMap(employeeRespDTOList, EmployeeRespDTO::getId, Function.identity());

            // // 参与人
            // List<Long> participantEmployeeIds = new ArrayList<>();
            // for (OaMeetingReserveDO oaMeetingReserveDO : oaMeetingReserveDOList) {
            //     String participants = oaMeetingReserveDO.getParticipants();
            //     if (StrUtil.isNotBlank(participants)) {
            //         String[] participantsStringArray = participants.split(",");
            //         List<Long> participantsLongList = Arrays.stream(participantsStringArray).map(Long::valueOf).collect(Collectors.toList());
            //         participantEmployeeIds.addAll(participantsLongList);
            //     }
            // }
            // List<AdminUserRespDTO> participantUserList = adminUserApi.getUserList(participantEmployeeIds);
            // Map<Long, AdminUserRespDTO> participantUserMap = participantUserList.stream().collect(Collectors.toMap(AdminUserRespDTO::getId, Function.identity()));

            // 状态描述
            Map<String, String> enumsMap = Arrays.stream(MeetingReserveStatusEnum.values())
                    .collect(Collectors.toMap(MeetingReserveStatusEnum::getStatus, MeetingReserveStatusEnum::getDesc));

            // 部门名称
            List<Long> deptIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getDeptId).collect(Collectors.toList());
            List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
            Map<Long, DeptRespDTO> deptMap = deptList.stream().collect(Collectors.toMap(DeptRespDTO::getId, Function.identity()));

            // 会议室名称
            List<Long> roomIds = oaMeetingReserveRespVOList.stream().map(OaMeetingReserveRespVO::getRoomId).collect(Collectors.toList());
            List<OaMeetingRoomRespDTO> roomList = oaMeetingRoomService.getOaMeetingRoomList(roomIds);
            Map<Long, OaMeetingRoomRespDTO> roomRespDTOMap = roomList.stream().collect(Collectors.toMap(OaMeetingRoomRespDTO::getId, Function.identity()));

            for (OaMeetingReserveRespVO oaMeetingReserveRespVO : oaMeetingReserveRespVOList) {
                // 申请人姓名
                Long applyEmployeeId = oaMeetingReserveRespVO.getApplyEmployeeId();
                if (applyEmployeeId != null) {
                    EmployeeRespDTO employeeRespDTO = employeeRespDTOMap.get(applyEmployeeId);
                    if (employeeRespDTO != null) {
                        oaMeetingReserveRespVO.setApplyEmployeeName(employeeRespDTO.getName());
                    }
                }
                // // 参与人姓名
                // String participants = oaMeetingReserveRespVO.getParticipants();
                // 状态描述
                String status = oaMeetingReserveRespVO.getStatus();
                oaMeetingReserveRespVO.setStatusDesc(enumsMap.get(status));
                // 部门名称
                Long deptId = oaMeetingReserveRespVO.getDeptId();
                if (deptId != null) {
                    DeptRespDTO dept = deptMap.get(deptId);
                    if (dept != null) {
                        oaMeetingReserveRespVO.setDepName(dept.getName());
                    }
                }
                // 会议室名称
                Long roomId = oaMeetingReserveRespVO.getRoomId();
                if (roomId != null) {
                    OaMeetingRoomRespDTO room = roomRespDTOMap.get(roomId);
                    if (room != null) {
                        oaMeetingReserveRespVO.setRoomName(room.getName());
                    }
                }
            }
        }
        // 导出 Excel
        ExcelUtils.write(response, "会议室预定管理信息.xls", "数据", OaMeetingReserveRespVO.class,
                oaMeetingReserveRespVOList);
    }

    @GetMapping("/cancel")
    @Operation(summary = "取消会议室预定管理信息")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:cancel')")
    public CommonResult<Boolean> cancelOaMeetingReserve(@RequestParam("id") Long id) {
        oaMeetingReserveService.cancelOaMeetingReserve(id);
        return success(true);
    }

    @GetMapping("/start")
    @Operation(summary = "开始会议室预定管理信息")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:start')")
    public CommonResult<Boolean> startOaMeetingReserve(@RequestParam("id") Long id) {
        oaMeetingReserveService.startOaMeetingReserve(id);
        return success(true);
    }

    @GetMapping("/end")
    @Operation(summary = "结束会议室预定管理信息")
    @Parameter(name = "id", description = "编号", required = true)
    // @PreAuthorize("@ss.hasPermission('bpm:oa-meeting-reserve:end')")
    public CommonResult<Boolean> endOaMeetingReserve(@RequestParam("id") Long id) {
        oaMeetingReserveService.endOaMeetingReserve(id);
        return success(true);
    }


}