package jnpf.attendance.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jnpf.attendance.service.AttendanceBookRecordService;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.attendance.dto.*;
import jnpf.model.attendance.vo.*;
import jnpf.util.FtbUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 考勤本记录表Controller
 * 
 * @author Generated
 * @create 2026-04-15
 */
@Slf4j
@RestController
@RequestMapping("/attendance/book-record")
@Tag(name = "考勤本记录", description = "考勤本记录管理")
public class AttendanceBookRecordController {

    @Resource
    private AttendanceBookRecordService attendanceBookRecordService;

    /**
     * app-新增或修改考勤记录（Upsert）
     * 根据考勤本ID、员工ID、考勤日期、时段类型唯一确定一条记录
     * 如果记录存在则更新，不存在则新增
     *
     * @param dto 考勤记录DTO
     * @return 操作结果（包含记录ID）
     */
    @Operation(summary = "app-新增或修改考勤记录")
    @PostMapping("/saveOrUpdate")
    public ActionResult<String> saveOrUpdate(@Valid @RequestBody AttendanceBookRecordDto dto) {
        try {
            log.info("新增或修改考勤记录，入参=>{}", JSONObject.toJSON(dto));
            long st = System.currentTimeMillis();
            
            String recordId = attendanceBookRecordService.saveOrUpdateRecord(dto);
            
            long ent = System.currentTimeMillis();
            log.info("新增或修改考勤记录，耗时=>{} 毫秒，记录ID: {}", ent - st, recordId);
            return ActionResult.success(recordId);
        } catch (Exception e) {
            log.error("新增或修改考勤记录异常", e);
            return ActionResult.fail("系统异常，请联系管理员");
        }
    }

    /**
     * web-获取考勤本月统计数据
     *
     * @param req 统计请求参数
     * @return 本月统计结果（按员工维度，支持分页）
     */
    @Operation(summary = "web/app-获取考勤本月统计")
    @PostMapping("/monthStatistics")
    public ActionResult<PageListVO<BookRecordMonthStatisticsVo>> getMonthStatistics(@Valid @RequestBody BookRecordMonthStatisticsDto req) {
        try {
            log.info("获取考勤本月统计，入参=>{}", JSONObject.toJSON(req));
            long st = System.currentTimeMillis();
            
            PageInfo<BookRecordMonthStatisticsVo> pageInfo = attendanceBookRecordService.getMonthStatistics(req);
            
            long ent = System.currentTimeMillis();
            // 防止pageInfo或list为null
            List<BookRecordMonthStatisticsVo> resultList = pageInfo.getList() != null ? pageInfo.getList() : new ArrayList<>();
            log.info("获取考勤本月统计，耗时=>{} 毫秒，返回记录数: {}", ent - st, resultList.size());
            return ActionResult.page(resultList, FtbUtil.getPagination(pageInfo));
        } catch (Exception e) {
            log.error("获取考勤本月统计异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * web-考勤本导入
     *
     * @param importDto 导入参数（包含bookId、month、fileUrl）
     * @return 操作结果
     */
    @Operation(summary = "web-考勤本导入")
    @PostMapping("/import")
    public ActionResult bookRecordImport(@RequestBody SchedulesImportDto importDto) {
        try {
            log.info("考勤本导入，入参=>{}", JSONObject.toJSON(importDto));
            attendanceBookRecordService.bookRecordImport(importDto);
            return ActionResult.success("导入成功");
        } catch (Exception e) {
            log.error("考勤本导入异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * web-考勤本导出
     *
     * @param bookId 考勤本ID
     * @param month  月份（格式：yyyy-MM）
     */
    @Operation(summary = "web-考勤本导出")
    @GetMapping("/export")
    public ActionResult bookRecordExport(@RequestParam String bookId, @RequestParam String month) {
        try {
            log.info("考勤本导出，bookId=>{}, month=>{}", bookId, month);
            attendanceBookRecordService.bookRecordExport(bookId, month);
        } catch (Exception e) {
            log.error("考勤本导出异常", e);
            throw new RuntimeException("导出失败：" + e.getMessage());
        }
        return ActionResult.success();
    }

    /**
     * web-导出考勤本模板（直接流导出）
     * <p>返回的Excel文件与导出接口具有相同的表头结构，但不包含任何实际数据记录</p>
     *
     * @param bookId 考勤本ID
     * @param month  月份（格式：yyyy-MM）
     * @param response HTTP响应对象
     */
    @Operation(summary = "web-导出考勤本模板")
    @GetMapping("/export-template")
    public void exportTemplate(@RequestParam String bookId, @RequestParam String month, javax.servlet.http.HttpServletResponse response) {
        try {
            log.info("导出考勤本模板，bookId=>{}, month=>{}", bookId, month);
            attendanceBookRecordService.exportTemplate(bookId, month, response);
        } catch (Exception e) {
            log.error("导出考勤本模板异常", e);
            throw new RuntimeException("导出模板失败：" + e.getMessage());
        }
    }

    /**
     * app-获取日考勤本列表
     * <p>根据考勤本的使用范围获取人员列表，展示指定日期的考勤记录</p>
     *
     * @param req 查询参数（考勤本ID、日期）
     * @return 日考勤本列表（按员工分组）
     */
    @Operation(summary = "app-获取日考勤本列表")
    @PostMapping("/day-list")
    public ActionResult<List<BookRecordDayListVo>> getDayList(@Valid @RequestBody BookRecordDayListDto req) {
        try {
            log.info("获取日考勤本列表，入参=>{}", JSONObject.toJSON(req));
            long st = System.currentTimeMillis();
            
            List<BookRecordDayListVo> result = attendanceBookRecordService.getDayList(req);
            
            long ent = System.currentTimeMillis();
            log.info("获取日考勤本列表，耗时=>{} 毫秒，返回记录数: {}", ent - st, result.size());
            return ActionResult.success(result);
        } catch (Exception e) {
            log.error("获取日考勤本列表异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * app-获取月考勤本列表
     * <p>根据考勤本的使用范围获取人员列表，展示该月所有日期的考勤记录</p>
     *
     * @param req 查询参数（考勤本ID、月份）
     * @return 月考勤本列表（按员工分组）
     */
    @Operation(summary = "app-获取月考勤本列表")
    @PostMapping("/month-list")
    public ActionResult<List<BookRecordMonthListVo>> getMonthList(@Valid @RequestBody BookRecordMonthListDto req) {
        try {
            log.info("获取月考勤本列表，入参=>{}", JSONObject.toJSON(req));
            long st = System.currentTimeMillis();
            
            List<BookRecordMonthListVo> result = attendanceBookRecordService.getMonthList(req);
            
            long ent = System.currentTimeMillis();
            log.info("获取月考勤本列表，耗时=>{} 毫秒，返回记录数: {}", ent - st, result.size());
            return ActionResult.success(result);
        } catch (Exception e) {
            log.error("获取月考勤本列表异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * 需求10：批量新增或修改考勤记录
     *
     * @param dto 批量考勤记录DTO
     * @return 批量操作结果
     */
    @Operation(summary = "app-批量新增或修改考勤记录")
    @PostMapping("/batch-save-or-update")
    public ActionResult<BatchOperationResultVo> batchSaveOrUpdate(@Valid @RequestBody BatchAttendanceBookRecordDto dto) {
        try {
            log.info("批量新增或修改考勤记录，记录数=>{}", dto.getRecords().size());
            long st = System.currentTimeMillis();
            
            BatchOperationResultVo result = attendanceBookRecordService.batchSaveOrUpdateRecord(dto);
            
            long ent = System.currentTimeMillis();
            log.info("批量新增或修改考勤记录，耗时=>{} 毫秒，成功: {}, 失败: {}", 
                    ent - st, result.getSuccessCount(), result.getFailCount());
            return ActionResult.success(result);
        } catch (Exception e) {
            log.error("批量新增或修改考勤记录异常", e);
            return ActionResult.fail("系统异常，请联系管理员");
        }
    }

    /**
     * 获取假勤汇总信息
     *
     * @param dto 统计请求参数
     * @return 假勤汇总信息
     */
    @Operation(summary = "app-获取假勤汇总信息")
    @PostMapping("/leave-attendance-summary")
    public ActionResult<LeaveRemarkSummaryVo> getLeaveAttendanceSummary(@Valid @RequestBody LeaveRemarkSummaryDto dto) {
        try {
            log.info("获取假勤汇总信息，入参=>{}", JSONObject.toJSON(dto));
            long st = System.currentTimeMillis();
            
            LeaveRemarkSummaryVo result = attendanceBookRecordService.getLeaveAttendanceSummary(dto);
            
            long ent = System.currentTimeMillis();
            log.info("获取假勤汇总信息，耗时=>{} 毫秒，备注数: {}", ent - st, result.getTotalCount());
            return ActionResult.success(result);
        } catch (Exception e) {
            log.error("获取假勤汇总信息异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }
}
