package org.hzhub.workflow.wecom;

import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.hzhub.common.core.domain.R;
import org.hzhub.common.core.validate.AddGroup;
import org.hzhub.common.excel.utils.ExcelUtil;
import org.hzhub.common.idempotent.annotation.RepeatSubmit;
import org.hzhub.common.log.annotation.Log;
import org.hzhub.common.log.enums.BusinessType;
import org.hzhub.common.mybatis.core.page.PageQuery;
import org.hzhub.common.mybatis.core.page.TableDataInfo;
import org.hzhub.workflow.domain.bo.WecomApprovalSubmitBo;
import org.hzhub.workflow.domain.vo.WecomApprovalVo;
import org.hzhub.workflow.service.IWecomApprovalService;
import org.hzhub.workflow.task.WecomApprovalSyncTask;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 企业微信审批控制器
 * <p>提供审批查询、提交、同步等接口</p>
 *
 * @author hzhub
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/wecom/approval")
public class WecomApprovalController {

    private final IWecomApprovalService wecomApprovalService;
    private final WecomApprovalSyncTask syncTask;

    /**
     * 分页查询审批列表
     */
    @GetMapping("/list")
    public TableDataInfo<WecomApprovalVo> list(
        @RequestParam(required = false) String type,
        @RequestParam(required = false) String status,
        @RequestParam(required = false) String keyword,
        PageQuery pageQuery) {
        return wecomApprovalService.listApprovals(type, status, keyword, pageQuery);
    }

    /**
     * 获取审批详情
     */
    @GetMapping("/{spNo}")
    public R<String> detail(@PathVariable @NotBlank(message = "审批单号不能为空") String spNo) {
        return R.ok(wecomApprovalService.getApprovalDetail(spNo));
    }

    /**
     * 发起审批申请
     */
    @Log(title = "企业微信审批", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping("/submit")
    public R<String> submit(@Validated(AddGroup.class) @RequestBody WecomApprovalSubmitBo bo) {
        String spNo = wecomApprovalService.submitApproval(bo);
        return R.ok("提交成功，审批单号: " + spNo, spNo);
    }

    /**
     * 异步触发全量同步（管理员使用）
     * <p>立即返回日志ID，前端轮询 /sync/logs 查看进度</p>
     *
     * @param daysBack 同步近 N 天数据，默认30天
     */
    @SaCheckPermission("wecom:approval:sync")
    @Log(title = "企业微信审批同步", businessType = BusinessType.OTHER)
    @PostMapping("/sync/full")
    public R<Long> syncFull(@RequestParam(defaultValue = "30") int daysBack) {
        Long logId = wecomApprovalService.syncAllApprovalsAsync(daysBack);
        return R.ok("已启动同步，请查看同步日志", logId);
    }

    /**
     * 同步当前用户近 1 天的审批数据
     */
    @RepeatSubmit
    @PostMapping("/sync/current")
    public R<String> syncCurrent() {
        String result = wecomApprovalService.syncCurrentUserApprovals();
        return R.ok(result);
    }

    /**
     * 查询同步日志
     */
    @GetMapping("/sync/logs")
    public TableDataInfo<Map<String, Object>> syncLogs(PageQuery pageQuery) {
        return wecomApprovalService.listSyncLogs(pageQuery);
    }

    /**
     * 获取审批模板列表
     */
    @GetMapping("/templates")
    public R<List<Map<String, Object>>> templates() {
        return R.ok(wecomApprovalService.listTemplates());
    }

    /**
     * 同步审批模板（管理员使用）
     * <p>从企业微信拉取所有审批模板并缓存到本地数据库</p>
     */
    @SaCheckPermission("wecom:approval:sync")
    @Log(title = "同步审批模板", businessType = BusinessType.OTHER)
    @PostMapping("/templates/sync")
    public R<String> syncTemplates() {
        wecomApprovalService.syncAllTemplates();
        return R.ok("模板同步完成");
    }

    /**
     * 获取统计数据
     */
    @GetMapping("/stats")
    public R<Map<String, Long>> stats() {
        return R.ok(wecomApprovalService.getStats());
    }

    /**
     * 获取当前用户统计数据
     */
    @GetMapping("/stats/user")
    public R<Map<String, Long>> userStats() {
        return R.ok(wecomApprovalService.getUserStats());
    }

    /**
     * 导出审批数据
     */
    @Log(title = "企业微信审批导出", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(@RequestParam(required = false) String status, HttpServletResponse response) {
        List<WecomApprovalVo> list = wecomApprovalService.listApprovals(null, status, null, new PageQuery(1, Integer.MAX_VALUE)).getRows();
        ExcelUtil.exportExcel(list, "审批数据", WecomApprovalVo.class, response);
    }

    /**
     * 获取定时任务状态
     */
    @SaCheckPermission("wecom:approval:sync")
    @GetMapping("/sync/task/status")
    public R<Map<String, Object>> getTaskStatus() {
        Map<String, Object> status = new LinkedHashMap<>();
        status.put("running", syncTask.isRunning());
        status.put("cron", syncTask.getCurrentCron() != null ? syncTask.getCurrentCron() : "0 0/5 * * * ?");
        return R.ok(status);
    }

    /**
     * 启动定时任务
     */
    @SaCheckPermission("wecom:approval:sync")
    @Log(title = "启动审批同步定时任务", businessType = BusinessType.OTHER)
    @PostMapping("/sync/task/start")
    public R<String> startTask() {
        syncTask.start();
        return R.ok("定时任务已启动");
    }

    /**
     * 停止定时任务
     */
    @SaCheckPermission("wecom:approval:sync")
    @Log(title = "停止审批同步定时任务", businessType = BusinessType.OTHER)
    @PostMapping("/sync/task/stop")
    public R<String> stopTask() {
        syncTask.stop();
        return R.ok("定时任务已停止");
    }

    /**
     * 设置定时任务频率
     */
    @SaCheckPermission("wecom:approval:sync")
    @Log(title = "设置审批同步频率", businessType = BusinessType.UPDATE)
    @PostMapping("/sync/task/cron")
    public R<String> setCron(@RequestParam String cron) {
        syncTask.setCron(cron);
        return R.ok("同步频率已更新: " + cron);
    }
}
