package com.ruoyi.web.report.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.report.domain.ErpReportDefinition;
import com.ruoyi.web.report.service.IErpReportDefinitionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
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.util.List;

/**
 * 报表定义管理控制器。
 *
 * <p>对外提供报表定义的标准管理接口，保持若依风格：
 * 权限控制 + 操作日志 + 统一返回结构。</p>
 */
@RestController
@RequestMapping("/erp/report/definition")
public class ErpReportDefinitionController extends BaseController {

    @Autowired
    private IErpReportDefinitionService erpReportDefinitionService;

    @PreAuthorize("@ss.hasPermi('erp:report:list')")
    @GetMapping("/list")
    public TableDataInfo list(ErpReportDefinition query) {
        // 复用若依分页能力，自动读取 pageNum/pageSize。
        startPage();
        List<ErpReportDefinition> list = erpReportDefinitionService.selectList(query);
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('erp:report:query')")
    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        // 详情查询用于编辑页回显和运行态读取元信息。
        return success(erpReportDefinitionService.selectById(id));
    }

    @PreAuthorize("@ss.hasPermi('erp:report:add')")
    @Log(title = "ERP报表定义", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ErpReportDefinition entity) {
        // 编码作为报表稳定标识，新增前必须保证唯一。
        if (!erpReportDefinitionService.checkReportCodeUnique(entity)) {
            return error("新增失败，报表编码已存在");
        }
        // 审计字段由后端统一注入，避免前端伪造。
        entity.setCreateBy(getUsername());
        entity.setUpdateBy(getUsername());
        return toAjax(erpReportDefinitionService.insert(entity));
    }

    @PreAuthorize("@ss.hasPermi('erp:report:edit')")
    @Log(title = "ERP报表定义", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ErpReportDefinition entity) {
        // 修改场景同样校验编码冲突（排除自身）。
        if (!erpReportDefinitionService.checkReportCodeUnique(entity)) {
            return error("修改失败，报表编码已存在");
        }
        entity.setUpdateBy(getUsername());
        return toAjax(erpReportDefinitionService.update(entity));
    }

    @PreAuthorize("@ss.hasPermi('erp:report:publish')")
    @Log(title = "ERP报表定义", businessType = BusinessType.UPDATE)
    @PostMapping("/{id}/publish")
    public AjaxResult publish(@PathVariable("id") Long id) {
        // 发布动作会触发状态切换与版本号提升。
        return toAjax(erpReportDefinitionService.publishById(id, getUsername()));
    }

    @PreAuthorize("@ss.hasPermi('erp:report:publish')")
    @Log(title = "ERP报表定义", businessType = BusinessType.UPDATE)
    @PostMapping("/rebuildMenus")
    public AjaxResult rebuildMenus() {
        // 对历史已发布报表补建菜单，适用于首次上线动态菜单能力后的数据修复。
        int count = erpReportDefinitionService.rebuildMenusForPublished(getUsername());
        return success("已完成菜单重建，处理报表数量：" + count);
    }

    @PreAuthorize("@ss.hasPermi('erp:report:publish')")
    @GetMapping("/{id}/menuDiagnostic")
    public AjaxResult menuDiagnostic(@PathVariable("id") Long id) {
        // 轻量诊断入口：仅菜单补建，不影响报表版本和状态。
        int count = erpReportDefinitionService.rebuildMenuByReportId(id, getUsername());
        return success(count > 0 ? "已触发菜单补建，请刷新页面并检查左侧菜单。" : "未找到报表，无法补建菜单。");
    }

    @PreAuthorize("@ss.hasPermi('erp:report:remove')")
    @Log(title = "ERP报表定义", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    public AjaxResult remove(@PathVariable("id") Long id) {
        // 删除前置校验（如被模板/任务引用）后续可在 Service 层补充。
        return toAjax(erpReportDefinitionService.removeById(id));
    }
}
