<script setup lang="tsx">
import { ref, reactive, computed, onMounted } from "vue";
import { message } from "@/utils/message";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { addDialog } from "@/components/ReDialog";
import {
  getAllPermissions,
  createPermission,
  updatePermission,
  deletePermission,
  togglePermissionStatus
} from "@/api/permission";
import type { PermissionItem, PermissionForm } from "../utils/types";
import { OPERATION_TYPES } from "../utils/types";

import Delete from "~icons/ep/delete";
import EditPen from "~icons/ep/edit-pen";
import Refresh from "~icons/ep/refresh";
import AddFill from "~icons/ri/add-circle-line";

defineOptions({
  name: "PermissionDefineDialog"
});

const props = withDefaults(defineProps<{
  onSaved?: () => void;
}>(), {});

const loading = ref(false);
const permissionList = ref<PermissionItem[]>([]);
const activeModule = ref("");
const tableRef = ref();
const switchLoadMap = ref({});

// 获取所有已启用的模块列表
const permissionModules = computed(() => {
  const moduleMap = new Map<string, string>();
  permissionList.value.forEach(p => {
    if (!moduleMap.has(p.moduleCode)) {
      moduleMap.set(p.moduleCode, p.moduleName);
    }
  });
  return Array.from(moduleMap.entries()).map(([code, name]) => ({
    code,
    name
  }));
});

// 根据模块筛选
const filteredList = computed(() => {
  if (!activeModule.value) return permissionList.value;
  return permissionList.value.filter(p => p.moduleCode === activeModule.value);
});

// 获取操作类型标签
function getOperationTypeTag(type: string) {
  const op = OPERATION_TYPES.find(t => t.value === type);
  if (!op) return { text: type, type: "info" };
  const colorMap: Record<string, string> = {
    read: "primary",
    create: "success",
    update: "warning",
    delete: "danger",
    export: "",
    import: "",
    execute: "info",
    distribute: "success",
    review: "warning",
    generate: ""
  };
  return { text: op.label, type: colorMap[type] || "info" };
}

// 表格列定义
const columns: TableColumnList = [
  {
    label: "权限编码",
    prop: "permissionCode",
    minWidth: 160
  },
  {
    label: "权限名称",
    prop: "permissionName",
    minWidth: 120
  },
  {
    label: "所属模块",
    prop: "moduleName",
    minWidth: 100
  },
  {
    label: "操作类型",
    prop: "operationType",
    minWidth: 90,
    cellRenderer: ({ row }) => {
      const tag = getOperationTypeTag(row.operationType);
      return <el-tag type={tag.type as any} size="small">{tag.text}</el-tag>;
    }
  },
  {
    label: "排序",
    prop: "sortOrder",
    width: 70
  },
  {
    label: "描述",
    prop: "description",
    minWidth: 140,
    showOverflowTooltip: true
  },
  {
    label: "状态",
    minWidth: 90,
    cellRenderer: ({ row, index }) => (
      <el-switch
        size="small"
        loading={switchLoadMap.value[index]?.loading}
        modelValue={row.status}
        active-value={1}
        inactive-value={0}
        active-text="启用"
        inactive-text="停用"
        inline-prompt
        onChange={(val) => handleToggleStatus(row, index, val)}
      />
    )
  },
  {
    label: "操作",
    fixed: "right",
    width: 140,
    cellRenderer: ({ row }) => (
      <div class="flex gap-2">
        <el-button
          link
          type="primary"
          size="small"
          icon={useRenderIcon(EditPen)}
          onClick={() => openFormDialog("编辑", row)}
        >
          编辑
        </el-button>
        <el-popconfirm
          title={`确认删除权限"${row.permissionName}"?`}
          onConfirm={() => handleDelete(row)}
        >
          {{
            reference: () => (
              <el-button
                link
                type="danger"
                size="small"
                icon={useRenderIcon(Delete)}
              >
                删除
              </el-button>
            )
          }}
        </el-popconfirm>
      </div>
    )
  }
];

// 获取数据
async function fetchData() {
  loading.value = true;
  try {
    const { data } = await getAllPermissions();
    permissionList.value = data || [];
  } catch (error) {
    console.error("获取权限列表失败:", error);
  } finally {
    loading.value = false;
  }
}

// 切换状态
async function handleToggleStatus(row: PermissionItem, index: number, val: number) {
  switchLoadMap.value[index] = { loading: true };
  try {
    const res = await togglePermissionStatus(row.id, val);
    if (res.code === 200) {
      row.status = val;
      message(`已${val === 1 ? "启用" : "停用"}权限 ${row.permissionName}`, { type: "success" });
    } else {
      message(res.message || "操作失败", { type: "error" });
    }
  } catch {
    message("操作失败", { type: "error" });
  } finally {
    switchLoadMap.value[index] = { loading: false };
  }
}

// 删除
async function handleDelete(row: PermissionItem) {
  try {
    const res = await deletePermission(row.id);
    if (res.code === 200) {
      message(`已删除权限 ${row.permissionName}`, { type: "success" });
      await fetchData();
    } else {
      message(res.message || "删除失败", { type: "error" });
    }
  } catch {
    message("删除失败", { type: "error" });
  }
}

// 打开新增/编辑表单弹窗
function openFormDialog(title: string, row?: PermissionItem) {
  const formData = reactive<PermissionForm>({
    permissionCode: row?.permissionCode || "",
    permissionName: row?.permissionName || "",
    moduleCode: row?.moduleCode || "",
    moduleName: row?.moduleName || "",
    operationType: row?.operationType || "read",
    description: row?.description || "",
    sortOrder: row?.sortOrder ?? 0,
    status: row?.status ?? 1
  });

  // 从现有权限中提取所有模块列表作为建议选项
  const moduleOptions = computed(() => {
    const map = new Map<string, string>();
    permissionList.value.forEach(p => {
      if (!map.has(p.moduleCode)) {
        map.set(p.moduleCode, p.moduleName);
      }
    });
    return Array.from(map.entries()).map(([code, name]) => ({ code, name }));
  });

  const ruleFormRef = ref();

  addDialog({
    title: `${title}权限`,
    width: "550px",
    draggable: true,
    closeOnClickModal: false,
    contentRenderer: () => (
      <el-form ref={ruleFormRef} model={formData} label-width="90px" label-position="right">
        <el-row gutter={20}>
          <el-col span={12}>
            <el-form-item
              label="权限编码"
              prop="permissionCode"
              rules={[
                { required: true, message: "请输入权限编码", trigger: "blur" },
                { pattern: /^[a-z][a-z0-9-]+:[a-z]+$/, message: "格式: module:operation (如 product:create)", trigger: "blur" }
              ]}
            >
              <el-input
                v-model={formData.permissionCode}
                placeholder="如 product:create"
                disabled={title === "编辑"}
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col span={12}>
            <el-form-item
              label="权限名称"
              prop="permissionName"
              rules={[{ required: true, message: "请输入权限名称", trigger: "blur" }]}
            >
              <el-input
                v-model={formData.permissionName}
                placeholder="如 商品创建"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row gutter={20}>
          <el-col span={12}>
            <el-form-item
              label="所属模块"
              prop="moduleCode"
              rules={[{ required: true, message: "请选择模块", trigger: "change" }]}
            >
              <el-select
                v-model={formData.moduleCode}
                placeholder="选择模块"
                clearable
                filterable
                allow-create
                style="width: 100%"
                onChange={(val: string) => {
                  if (title === "新增") {
                    const found = moduleOptions.value.find(m => m.code === val);
                    if (found) {
                      formData.moduleName = found.name;
                    } else {
                      formData.moduleName = val;
                    }
                  }
                }}
              >
                {moduleOptions.value.map(m => (
                  <el-option key={m.code} label={`${m.name} (${m.code})`} value={m.code} />
                ))}
              </el-select>
            </el-form-item>
          </el-col>
          <el-col span={12}>
            <el-form-item label="模块名称" prop="moduleName">
              <el-input
                v-model={formData.moduleName}
                placeholder="自动填充或手动输入"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row gutter={20}>
          <el-col span={12}>
            <el-form-item
              label="操作类型"
              prop="operationType"
              rules={[{ required: true, message: "请选择操作类型", trigger: "change" }]}
            >
              <el-select v-model={formData.operationType} placeholder="选择操作类型" style="width: 100%">
                {OPERATION_TYPES.map(op => (
                  <el-option key={op.value} label={op.label} value={op.value} />
                ))}
              </el-select>
            </el-form-item>
          </el-col>
          <el-col span={12}>
            <el-form-item label="排序号" prop="sortOrder">
              <el-input
                v-model={formData.sortOrder}
                type="number"
                min={0}
                max={999}
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="状态" prop="status">
          <el-radio-group v-model={formData.status}>
            <el-radio value={1}>启用</el-radio>
            <el-radio value={0}>停用</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="描述" prop="description">
          <el-input
            v-model={formData.description}
            type="textarea"
            placeholder="权限描述说明"
            rows={2}
          />
        </el-form-item>
      </el-form>
    ),
    beforeSure: async (done) => {
      const valid = await ruleFormRef.value?.validate().catch(() => false);
      if (!valid) return;

      try {
        if (title === "新增") {
          const res = await createPermission({ ...formData });
          if (res.code === 200) {
            message(`新增权限 ${formData.permissionName} 成功`, { type: "success" });
            done();
            await fetchData();
          } else {
            message(res.message || "新增失败", { type: "error" });
          }
        } else {
          const res = await updatePermission({ id: row.id, ...formData });
          if (res.code === 200) {
            message(`编辑权限 ${formData.permissionName} 成功`, { type: "success" });
            done();
            await fetchData();
          } else {
            message(res.message || "编辑失败", { type: "error" });
          }
        }
      } catch (error) {
        message("操作失败", { type: "error" });
      }
    }
  });
}

onMounted(() => {
  fetchData();
});

// 刷新
function handleRefresh() {
  fetchData();
}

defineExpose({
  handleRefresh
});
</script>

<template>
  <div class="permission-define-dialog">
    <!-- 模块筛选 -->
    <el-form class="search-form" inline>
      <el-form-item label="模块筛选：">
        <el-radio-group v-model="activeModule">
          <el-radio-button value="">全部</el-radio-button>
          <el-radio-button
            v-for="mod in permissionModules"
            :key="mod.code"
            :value="mod.code"
          >
            {{ mod.name }}
          </el-radio-button>
        </el-radio-group>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          :icon="useRenderIcon(AddFill)"
          @click="openFormDialog('新增')"
        >
          新增权限
        </el-button>
        <el-button
          :icon="useRenderIcon(Refresh)"
          @click="handleRefresh"
        >
          刷新
        </el-button>
      </el-form-item>
    </el-form>

    <pure-table
      ref="tableRef"
      row-key="id"
      border
      stripe
      align-whole="center"
      table-layout="auto"
      :loading="loading"
      :data="filteredList"
      :columns="columns"
      :header-cell-style="{
        background: 'var(--el-fill-color-light)',
        color: 'var(--el-text-color-primary)'
      }"
    />
  </div>
</template>

<style lang="scss" scoped>
.permission-define-dialog {
  height: 100%;
  display: flex;
  flex-direction: column;

  .search-form {
    flex-shrink: 0;
    margin-bottom: 12px;

    :deep(.el-form-item) {
      margin-bottom: 0;
    }
  }
}
</style>
