package com.njcn.rdms.module.project.controller.admin.overtime;

import com.njcn.rdms.framework.apilog.core.annotation.ApiAccessLog;
import com.njcn.rdms.framework.common.pojo.CommonResult;
import com.njcn.rdms.framework.common.pojo.PageResult;
import com.njcn.rdms.framework.excel.core.util.ExcelUtils;
import com.njcn.rdms.module.project.constant.OvertimeApplicationConstants;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationApprovalRecordRespVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationBatchActionReqVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationBatchResultRespVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationExportVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationPageReqVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationRespVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationSaveReqVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationStatusActionReqVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationStatusDictRespVO;
import com.njcn.rdms.module.project.controller.admin.overtime.vo.OvertimeApplicationStatusLogRespVO;
import com.njcn.rdms.module.project.service.overtime.OvertimeApplicationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;

import static com.njcn.rdms.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 加班申请")
@RestController
@RequestMapping("/project/overtime-applications")
@Validated
public class OvertimeApplicationController {

    @Resource
    private OvertimeApplicationService overtimeApplicationService;

    @PostMapping
    @Operation(summary = "新增加班申请并提交")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_CREATE + "')")
    public CommonResult<Long> create(@Valid @RequestBody OvertimeApplicationSaveReqVO reqVO) {
        return success(overtimeApplicationService.createApplication(reqVO));
    }

    @PutMapping("/{id}")
    @Operation(summary = "退回后修改并重新提交加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_UPDATE + "')")
    public CommonResult<Boolean> resubmit(@PathVariable("id") Long id,
                                          @Valid @RequestBody OvertimeApplicationSaveReqVO reqVO) {
        overtimeApplicationService.resubmitApplication(id, reqVO);
        return success(true);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取加班申请详情")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_QUERY + "')")
    public CommonResult<OvertimeApplicationRespVO> get(@PathVariable("id") Long id) {
        return success(overtimeApplicationService.getApplication(id));
    }

    @GetMapping("/status/dict")
    @Operation(summary = "获取加班申请所有状态字典")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_QUERY + "')")
    public CommonResult<List<OvertimeApplicationStatusDictRespVO>> getStatusDict() {
        return success(overtimeApplicationService.getStatusDict());
    }

    @GetMapping("/page")
    @Operation(summary = "获取我的加班申请分页")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_QUERY + "')")
    public CommonResult<PageResult<OvertimeApplicationRespVO>> page(@Valid OvertimeApplicationPageReqVO reqVO) {
        return success(overtimeApplicationService.getMyPage(reqVO));
    }

    @GetMapping("/approval-page")
    @Operation(summary = "获取待我审批的加班申请分页")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_APPROVE + "')")
    public CommonResult<PageResult<OvertimeApplicationRespVO>> approvalPage(@Valid OvertimeApplicationPageReqVO reqVO) {
        return success(overtimeApplicationService.getApprovalPage(reqVO));
    }

    @PostMapping("/{id}/approve")
    @Operation(summary = "审核通过加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_APPROVE + "')")
    public CommonResult<Boolean> approve(@PathVariable("id") Long id,
                                         @Valid @RequestBody OvertimeApplicationStatusActionReqVO reqVO) {
        overtimeApplicationService.approve(id, reqVO);
        return success(true);
    }

    @PostMapping("/{id}/reject")
    @Operation(summary = "审核退回加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_APPROVE + "')")
    public CommonResult<Boolean> reject(@PathVariable("id") Long id,
                                        @Valid @RequestBody OvertimeApplicationStatusActionReqVO reqVO) {
        overtimeApplicationService.reject(id, reqVO);
        return success(true);
    }

    @PostMapping("/batch-approve")
    @Operation(summary = "批量审核通过加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_APPROVE + "')")
    public CommonResult<OvertimeApplicationBatchResultRespVO> batchApprove(
            @Valid @RequestBody OvertimeApplicationBatchActionReqVO reqVO) {
        return success(overtimeApplicationService.batchApprove(reqVO));
    }

    @PostMapping("/batch-reject")
    @Operation(summary = "批量审核退回加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_APPROVE + "')")
    public CommonResult<OvertimeApplicationBatchResultRespVO> batchReject(
            @Valid @RequestBody OvertimeApplicationBatchActionReqVO reqVO) {
        return success(overtimeApplicationService.batchReject(reqVO));
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除已退回的加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_DELETE + "')")
    public CommonResult<Boolean> delete(@PathVariable("id") Long id) {
        overtimeApplicationService.deleteApplication(id);
        return success(true);
    }

    @GetMapping("/{id}/status-logs")
    @Operation(summary = "获取加班申请状态日志")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_QUERY + "')")
    public CommonResult<List<OvertimeApplicationStatusLogRespVO>> statusLogs(@PathVariable("id") Long id) {
        return success(overtimeApplicationService.getStatusLogs(id));
    }

    @GetMapping("/{id}/approval-records")
    @Operation(summary = "获取加班申请审核记录")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_QUERY + "')")
    public CommonResult<List<OvertimeApplicationApprovalRecordRespVO>> approvalRecords(@PathVariable("id") Long id) {
        return success(overtimeApplicationService.getApprovalRecords(id));
    }

    @GetMapping("/export")
    @Operation(summary = "导出我的加班申请")
    @PreAuthorize("@ss.hasPermission('" + OvertimeApplicationConstants.PERMISSION_EXPORT + "')")
    @ApiAccessLog(operateType = EXPORT)
    public void export(@Valid OvertimeApplicationPageReqVO reqVO, HttpServletResponse response) throws IOException {
        List<OvertimeApplicationExportVO> list = overtimeApplicationService.getExportList(reqVO);
        ExcelUtils.write(response, "加班申请_" + LocalDate.now() + ".xls", "加班申请",
                OvertimeApplicationExportVO.class, list);
    }
}
