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

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.module.project.constant.PerformanceConstants;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceMonthlyResultRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetBatchDownloadReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetCreateReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetExcelUpdateReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetImportZipReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetImportZipRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPageReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPrefillRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetResponseRecordRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetSignOffReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusActionReqVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusDictRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusLogRespVO;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetStatusTransitionRespVO;
import com.njcn.rdms.module.project.service.performance.PerformanceDownloadFile;
import com.njcn.rdms.module.project.service.performance.PerformanceSheetService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
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/performance-sheets")
@Validated
public class PerformanceSheetController {

    @Resource
    private PerformanceSheetService performanceSheetService;

    @GetMapping("/page")
    @Operation(summary = "获取绩效表分页")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<PageResult<PerformanceSheetRespVO>> page(@Valid PerformanceSheetPageReqVO reqVO) {
        return success(performanceSheetService.getSheetPage(reqVO));
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取绩效表详情")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<PerformanceSheetRespVO> get(@PathVariable("id") Long id) {
        return success(performanceSheetService.getSheet(id));
    }

    @PostMapping
    @Operation(summary = "创建绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_CREATE + "')")
    public CommonResult<Long> create(@Valid @RequestBody PerformanceSheetCreateReqVO reqVO) {
        return success(performanceSheetService.createSheet(reqVO));
    }

    @PutMapping("/{id}/excel")
    @Operation(summary = "保存绩效 Excel")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_UPDATE + "')")
    public CommonResult<Boolean> updateExcel(@PathVariable("id") Long id,
                                             @Valid @RequestBody PerformanceSheetExcelUpdateReqVO reqVO) {
        performanceSheetService.updateExcel(id, reqVO);
        return success(true);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_DELETE + "')")
    public CommonResult<Boolean> delete(@PathVariable("id") Long id) {
        performanceSheetService.deleteSheet(id);
        return success(true);
    }

    @PostMapping("/{id}/send")
    @Operation(summary = "发送绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_UPDATE + "')")
    public CommonResult<Boolean> send(@PathVariable("id") Long id) {
        performanceSheetService.send(id);
        return success(true);
    }

    @PostMapping("/{id}/resend")
    @Operation(summary = "重新发送绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_UPDATE + "')")
    public CommonResult<Boolean> resend(@PathVariable("id") Long id) {
        performanceSheetService.resend(id);
        return success(true);
    }

    @PostMapping("/{id}/confirm")
    @Operation(summary = "员工确认绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_CONFIRM + "')")
    public CommonResult<Boolean> confirm(@PathVariable("id") Long id,
                                         @Valid @RequestBody(required = false) PerformanceSheetStatusActionReqVO reqVO) {
        performanceSheetService.confirm(id, reqVO);
        return success(true);
    }

    @PostMapping("/{id}/reject")
    @Operation(summary = "员工退回绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_REJECT + "')")
    public CommonResult<Boolean> reject(@PathVariable("id") Long id,
                                        @Valid @RequestBody PerformanceSheetStatusActionReqVO reqVO) {
        performanceSheetService.reject(id, reqVO);
        return success(true);
    }

    @PostMapping("/import-zip")
    @Operation(summary = "导入绩效压缩包")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_IMPORT + "')")
    public CommonResult<PerformanceSheetImportZipRespVO> importZip(@Valid PerformanceSheetImportZipReqVO reqVO)
            throws Exception {
        return success(performanceSheetService.importZip(reqVO));
    }

    @PostMapping("/sign-off")
    @Operation(summary = "一键下签")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_SIGN_OFF + "')")
    public CommonResult<Long> signOff(@Valid @RequestBody PerformanceSheetSignOffReqVO reqVO) {
        return success(performanceSheetService.signOff(reqVO));
    }

    @GetMapping("/{id}/download")
    @Operation(summary = "下载单条绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_EXPORT + "')")
    @ApiAccessLog(operateType = EXPORT)
    public void download(@PathVariable("id") Long id, HttpServletResponse response) throws IOException {
        writeDownload(response, performanceSheetService.download(id));
    }

    @PostMapping("/batch-download")
    @Operation(summary = "批量下载绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_EXPORT + "')")
    @ApiAccessLog(operateType = EXPORT)
    public void batchDownload(@Valid @RequestBody PerformanceSheetBatchDownloadReqVO reqVO,
                              HttpServletResponse response) throws IOException {
        writeDownload(response, performanceSheetService.batchDownload(reqVO.getIds()));
    }

    @GetMapping("/export")
    @Operation(summary = "按筛选条件导出绩效表")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_EXPORT + "')")
    @ApiAccessLog(operateType = EXPORT)
    public void export(@Valid PerformanceSheetPageReqVO reqVO, HttpServletResponse response) throws IOException {
        writeDownload(response, performanceSheetService.exportByCondition(reqVO));
    }

    @GetMapping("/{id}/status-logs")
    @Operation(summary = "获取绩效表状态日志")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<List<PerformanceSheetStatusLogRespVO>> statusLogs(@PathVariable("id") Long id) {
        return success(performanceSheetService.getStatusLogs(id));
    }

    @GetMapping("/{id}/response-records")
    @Operation(summary = "获取绩效表员工反馈历史")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<List<PerformanceSheetResponseRecordRespVO>> responseRecords(@PathVariable("id") Long id) {
        return success(performanceSheetService.getResponseRecords(id));
    }

    @GetMapping("/prefill")
    @Operation(summary = "获取绩效表上一份预填充数据")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_CREATE + "')")
    public CommonResult<PerformanceSheetPrefillRespVO> prefill(@RequestParam("employeeId") Long employeeId,
                                                               @RequestParam("periodMonth") String periodMonth) {
        return success(performanceSheetService.getPrefillData(employeeId, periodMonth));
    }

    @GetMapping("/monthly-result")
    @Operation(summary = "获取月报审批绩效结果")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<PerformanceMonthlyResultRespVO> monthlyResult(@RequestParam("employeeId") Long employeeId,
                                                                      @RequestParam("periodMonth") String periodMonth) {
        return success(performanceSheetService.getMonthlyResult(employeeId, periodMonth));
    }

    @GetMapping("/status-dict")
    @Operation(summary = "获取绩效表状态字典")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<List<PerformanceSheetStatusDictRespVO>> statusDict() {
        return success(performanceSheetService.getStatusDict());
    }

    @GetMapping("/status-transitions")
    @Operation(summary = "获取绩效表状态动作字典")
    @PreAuthorize("@ss.hasPermission('" + PerformanceConstants.PERMISSION_SHEET_QUERY + "')")
    public CommonResult<List<PerformanceSheetStatusTransitionRespVO>> statusTransitions() {
        return success(performanceSheetService.getStatusTransitions());
    }

    private void writeDownload(HttpServletResponse response, PerformanceDownloadFile file) throws IOException {
        response.setContentType(file.contentType());
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''"
                + URLEncoder.encode(file.filename(), StandardCharsets.UTF_8).replace("+", "%20"));
        response.setContentLength(file.content().length);
        response.getOutputStream().write(file.content());
    }
}
