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.AttendanceBookConfigService;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.exception.HandleException;
import jnpf.model.attendance.dto.*;
import jnpf.model.attendance.vo.AttendanceBookConfigVo;
import jnpf.model.attendance.vo.AttendanceResultOptionGroupVo;
import jnpf.model.attendance.vo.AttendanceResultOptionVo;
import jnpf.model.attendance.vo.BookConfigCreatorVo;
import jnpf.model.attendance.vo.BookPersonnelVo;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.util.FtbUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

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

/**
 * 考勤本配置Controller
 *
 * @author Generated
 * @create 2026-04-15
 */
@Slf4j
@RestController
@RequestMapping("/attendance/book-config")
@Tag(name = "考勤本配置", description = "考勤本配置管理")
public class AttendanceBookConfigController {

    @Resource
    private AttendanceBookConfigService attendanceBookConfigService;

    /**
     * web-分页查询考勤本配置列表
     *
     * @param queryDto 查询条件
     * @return 分页结果
     */
    @Operation(summary = "web/app-分页查询考勤本配置列表(app用于当前登录人为负责人的考勤本列表)")
    @PostMapping("/list")
    public ActionResult<PageListVO<AttendanceBookConfigVo>> getList(@RequestBody AttendanceBookConfigQueryDto queryDto) {
        try {
            log.info("分页查询考勤本配置列表，入参=>{}", JSONObject.toJSON(queryDto));
            long st = System.currentTimeMillis();
            
            PageInfo<AttendanceBookConfigVo> pageInfo = attendanceBookConfigService.getPageList(queryDto);
            
            long ent = System.currentTimeMillis();
            log.info("分页查询考勤本配置列表，耗时=>{} 毫秒", ent - st);
            return ActionResult.page(pageInfo.getList(), FtbUtil.getPagination(pageInfo));
        } catch (Exception e) {
            log.error("分页查询考勤本配置列表异常", e);
            return ActionResult.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * web-新增或更新考勤本配置
     * <p>根据DTO中的id判断：id为空则新增，id不为空则更新</p>
     *
     * @param configDto 考勤本配置DTO
     * @return 操作结果
     */
    @Operation(summary = "web-新增或更新考勤本配置")
    @PostMapping("/save-or-update")
    public ActionResult saveOrUpdate(@Valid @RequestBody AttendanceBookConfigDto configDto) {
        try {
            String action = StringUtils.isBlank(configDto.getId()) ? "新增" : "更新";
            log.info("{}考勤本配置，入参=>{}", action, JSONObject.toJSON(configDto));
            long st = System.currentTimeMillis();
            
            attendanceBookConfigService.saveOrUpdateAttendanceBookConfig(configDto);
            
            long ent = System.currentTimeMillis();
            log.info("{}考勤本配置，耗时=>{} 毫秒", action, ent - st);
            return ActionResult.success(action + "成功");
        } catch (HandleException e) {
            log.error("保存考勤本配置业务异常", e);
            return ActionResult.fail(e.getMessage());
        } catch (Exception e) {
            log.error("保存考勤本配置异常", e);
            return ActionResult.fail("保存失败：" + e.getMessage());
        }
    }

    /**
     * web-删除考勤本配置
     *
     * @param id 考勤本ID
     * @return 操作结果
     */
    @Operation(summary = "web-删除考勤本配置")
    @DeleteMapping("/{id}")
    public ActionResult delete(@PathVariable String id) {
        try {
            log.info("删除考勤本配置，id=>{}", id);
            attendanceBookConfigService.deleteAttendanceBookConfig(id);
            return ActionResult.success("删除成功");
        } catch (Exception e) {
            log.error("删除考勤本配置异常", e);
            return ActionResult.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * web-更新启用状态
     *
     * @param id 考勤本ID
     * @return 操作结果
     */
    @Operation(summary = "web-更新启用状态")
    @PutMapping("/{id}/status")
    public ActionResult updateStatus(@PathVariable String id) {
        try {
            log.info("更新考勤本启用状态，id=>{}", id);
            attendanceBookConfigService.updateEnableStatus(id);
            return ActionResult.success("状态更新成功");
        } catch (HandleException e) {
            log.error("更新考勤本状态业务异常", e);
            return ActionResult.fail(e.getMessage());
        } catch (Exception e) {
            log.error("更新考勤本状态异常", e);
            return ActionResult.fail("状态更新失败：" + e.getMessage());
        }
    }

    /**
     * web-获取考勤本配置详情
     *
     * @param id 考勤本ID
     * @return 考勤本配置详情
     */
    @Operation(summary = "web-获取考勤本配置详情")
    @GetMapping("/{id}")
    public ActionResult<AttendanceBookConfigVo> getDetail(@PathVariable String id) {
        try {
            log.info("获取考勤本配置详情，id=>{}", id);
            AttendanceBookConfigVo vo = attendanceBookConfigService.getDetail(id);
            return ActionResult.success(vo);
        } catch (Exception e) {
            log.error("获取考勤本配置详情异常", e);
            return ActionResult.fail("获取详情失败：" + e.getMessage());
        }
    }

    /**
     * app-增量添加使用范围人员
     * <p>向指定考勤本配置的使用范围中增量添加用户列表（不会覆盖已有人员）</p>
     *
     * @param addUserDto 添加用户DTO
     * @return 操作结果
     */
    @Operation(summary = "app-增量添加使用范围人员")
    @PostMapping("/add-scope-users")
    public ActionResult addScopeUsers(@Valid @RequestBody AttendanceBookConfigAddUserDto addUserDto) {
        try {
            log.info("增量添加使用范围人员，考勤本ID=>{}, 用户数=>{}", 
                    addUserDto.getBookConfigId(), addUserDto.getUserIdList().size());
            long st = System.currentTimeMillis();
            
            attendanceBookConfigService.addScopeUsers(addUserDto);
            
            long ent = System.currentTimeMillis();
            log.info("增量添加使用范围人员，耗时=>{} 毫秒", ent - st);
            return ActionResult.success("添加成功");
        } catch (HandleException e) {
            log.error("增量添加使用范围人员业务异常", e);
            return ActionResult.fail(e.getMessage());
        } catch (Exception e) {
            log.error("增量添加使用范围人员异常", e);
            return ActionResult.fail("添加失败：" + e.getMessage());
        }
    }

    /**
     * app-判断当前登录人是否为考勤本负责人
     *
     * @param bookConfigId 考勤本配置ID
     * @return true-是负责人，false-不是负责人
     */
    @Operation(summary = "app-判断当前登录人是否为考勤本负责人")
    @GetMapping("/{bookConfigId}/is-manager")
    public ActionResult<Boolean> isCurrentUserManager(@PathVariable String bookConfigId) {
        try {
            log.info("判断当前登录人是否为考勤本负责人，考勤本ID=>{}", bookConfigId);
            boolean isManager = attendanceBookConfigService.isCurrentUserManager(bookConfigId);
            return ActionResult.success(isManager);
        } catch (HandleException e) {
            log.error("判断负责人业务异常", e);
            return ActionResult.fail(e.getMessage());
        } catch (Exception e) {
            log.error("判断负责人异常", e);
            return ActionResult.fail("判断失败：" + e.getMessage());
        }
    }

    /**
     * web-获取指定组织集合及用户集合在当前时间下的所有涉及用户(筛选考勤本负责人)
     * <p>查询这些组织和用户在当前时间的有效用户集合，返回完整的用户信息列表</p>
     *
     * @param dto 查询参数（组织ID列表、用户ID列表）
     * @return 有效用户信息列表
     */
    @Operation(summary = "web-获取指定组织集合及用户集合在当前时间下的所有涉及用户(筛选考勤本负责人)")
    @PostMapping("/get-valid-users")
    public ActionResult<List<PartUserInfoVo>> getValidUsers(@RequestBody GetValidUsersDto dto) {
        try {
            log.info("获取有效用户列表，入参=>{}", JSONObject.toJSON(dto));
            long st = System.currentTimeMillis();
            
            List<PartUserInfoVo> userList = attendanceBookConfigService.getValidUsers(dto);
            
            long ent = System.currentTimeMillis();
            log.info("获取有效用户列表，耗时=>{} 毫秒，返回用户数: {}", ent - st, userList.size());
            return ActionResult.success(userList);
        } catch (Exception e) {
            log.error("获取有效用户列表异常", e);
            return ActionResult.fail(e.getMessage());
        }
    }

    /**
     * app-获取考勤结果下拉列表
     * <p>根据考勤本配置返回可用的考勤状态选项，包括基础考勤状态和该考勤本配置的请假类型</p>
     *
     * @param bookConfigId 考勤本配置ID
     * @return 考勤结果下拉选项列表
     */
    @Operation(summary = "app-获取考勤结果下拉列表（分组）")
    @GetMapping("/{bookConfigId}/result-options")
    public ActionResult<AttendanceResultOptionGroupVo> getAttendanceResultOptions(@PathVariable String bookConfigId) {
        try {
            log.info("获取考勤结果下拉列表（分组），考勤本ID=>{}", bookConfigId);
            long st = System.currentTimeMillis();
            
            AttendanceResultOptionGroupVo options = attendanceBookConfigService.getAttendanceResultOptions(bookConfigId);
            
            long ent = System.currentTimeMillis();
            log.info("获取考勤结果下拉列表（分组），耗时=>{} 毫秒", ent - st);
            return ActionResult.success(options);
        } catch (HandleException e) {
            log.error("获取考勤结果下拉列表业务异常", e);
            return ActionResult.fail(e.getMessage());
        } catch (Exception e) {
            log.error("获取考勤结果下拉列表异常", e);
            return ActionResult.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 需求2：获取考勤本配置创建人列表
     *
     * @return 创建人列表
     */
    @Operation(summary = "web-获取考勤本配置创建人列表")
    @GetMapping("/creator-list")
    public ActionResult<List<BookConfigCreatorVo>> getCreatorList() {
        try {
            log.info("获取考勤本配置创建人列表");
            long st = System.currentTimeMillis();
            
            List<BookConfigCreatorVo> creatorList = attendanceBookConfigService.getCreatorList();
            
            long ent = System.currentTimeMillis();
            log.info("获取考勤本配置创建人列表，耗时=>{} 毫秒，创建人数: {}", ent - st, creatorList.size());
            return ActionResult.success(creatorList);
        } catch (Exception e) {
            log.error("获取考勤本配置创建人列表异常", e);
            return ActionResult.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 需求3：获取考勤本配置人员列表
     *
     * @param dto 考勤本配置ID
     * @return 人员列表
     */
    @Operation(summary = "app-获取考勤本配置人员列表")
    @PostMapping("/personnel-list")
    public ActionResult<List<BookPersonnelVo>> getPersonnelList(@RequestBody BookRecordMonthListDto dto) {
        try {
            log.info("获取考勤本配置人员列表，考勤本ID=>{}", dto.getBookId());
            long st = System.currentTimeMillis();
            
            List<BookPersonnelVo> personnelList = attendanceBookConfigService.getBookPersonnelList(dto.getBookId(),dto.getMonth());
            
            long ent = System.currentTimeMillis();
            log.info("获取考勤本配置人员列表，耗时=>{} 毫秒，人员数: {}", ent - st, personnelList.size());
            return ActionResult.success(personnelList);
        } catch (Exception e) {
            log.error("获取考勤本配置人员列表异常", e);
            return ActionResult.fail("获取失败：" + e.getMessage());
        }
    }
}
