<template>
  <div class="review-rules-page">
    <a-card class="mb-4">
      <template #title>评审规则</template>
      <template #extra>
        <a-button
          v-permission="'contest:update'"
          type="primary"
          @click="handleAdd"
          >新建规则</a-button
        >
      </template>
    </a-card>

    <!-- 搜索表单 -->
    <a-form
      :model="searchParams"
      layout="inline"
      class="search-form"
      @finish="handleSearch"
    >
      <a-form-item label="规则名称">
        <a-input
          v-model:value="searchParams.ruleName"
          placeholder="请输入规则名称"
          allow-clear
          style="width: 200px"
        />
      </a-form-item>
      <a-form-item>
        <a-button type="primary" html-type="submit">
          <template #icon><SearchOutlined /></template>
          搜索
        </a-button>
        <a-button style="margin-left: 8px" @click="handleReset">
          <template #icon><ReloadOutlined /></template>
          重置
        </a-button>
      </a-form-item>
    </a-form>

    <!-- 数据表格 -->
    <a-table
      :columns="columns"
      :data-source="dataSource"
      :loading="loading"
      :pagination="pagination"
      row-key="id"
      @change="handleTableChange"
    >
      <template #bodyCell="{ column, record, index }">
        <template v-if="column.key === 'index'">
          {{ (pagination.current - 1) * pagination.pageSize + index + 1 }}
        </template>
        <template v-else-if="column.key === 'ruleDescription'">
          <span>{{ formatDimensions(record.dimensions) }}</span>
        </template>
        <template v-else-if="column.key === 'contests'">
          <span v-if="record.contests && record.contests.length > 0">
            {{ record.contests.map((c: any) => c.contestName).join("、") }}
          </span>
          <span v-else>-</span>
        </template>
        <template v-else-if="column.key === 'action'">
          <a-space>
            <a-button
              v-permission="'contest:update'"
              type="link"
              size="small"
              @click="handleEdit(record)"
            >
              编辑
            </a-button>
            <a-popconfirm
              v-permission="'contest:update'"
              title="确定要删除这个评审规则吗？"
              @confirm="handleDelete(record.id)"
            >
              <a-button type="link" danger size="small">删除</a-button>
            </a-popconfirm>
          </a-space>
        </template>
      </template>
    </a-table>

    <!-- 新增/编辑评审规则抽屉 -->
    <a-drawer
      v-model:open="modalVisible"
      title="编辑规则"
      placement="right"
      width="600px"
      :footer-style="{ textAlign: 'right' }"
    >
      <a-form
        ref="formRef"
        :model="form"
        :rules="rules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 18 }"
      >
        <a-form-item label="规则名称" name="ruleName">
          <a-input
            v-model:value="form.ruleName"
            placeholder="请输入规则名称"
            :maxlength="100"
          />
        </a-form-item>
        <a-form-item label="规则说明" name="ruleDescription">
          <a-textarea
            v-model:value="form.ruleDescription"
            placeholder="请输入规则说明"
            :rows="4"
            :maxlength="500"
          />
        </a-form-item>
        <a-form-item label="评委数量" name="judgeCount">
          <a-input-number
            v-model:value="form.judgeCount"
            placeholder="请输入评委数量"
            :min="1"
            style="width: 100%"
          />
        </a-form-item>
        <a-form-item label="评分标准" name="dimensions" required>
          <div class="scoring-standards">
            <div
              v-for="(dimension, index) in form.dimensions"
              :key="index"
              class="scoring-standard-item"
            >
              <a-row :gutter="16" class="scoring-input-row">
                <a-col :span="12">
                  <a-input
                    v-model:value="dimension.name"
                    placeholder="请输入评分项,如创意分、技术分"
                    :maxlength="50"
                  />
                </a-col>
                <a-col :span="8">
                  <a-input-number
                    v-model:value="dimension.percentage"
                    placeholder="请输入分值"
                    :min="0"
                    :max="100"
                    :precision="2"
                    style="width: 100%"
                  >
                    <template #addonAfter>%</template>
                  </a-input-number>
                </a-col>
                <a-col
                  :span="4"
                  style="
                    display: flex;
                    align-items: center;
                    justify-content: center;
                  "
                >
                  <a-button
                    v-if="form.dimensions.length > 1"
                    type="text"
                    danger
                    @click="removeDimension(index)"
                    style="padding: 0; height: auto"
                  >
                    <template #icon><DeleteOutlined /></template>
                  </a-button>
                </a-col>
              </a-row>
              <a-textarea
                v-model:value="dimension.description"
                placeholder="请输入评分标准说明"
                :rows="2"
                :maxlength="150"
                show-count
                style="margin-top: 12px"
              />
            </div>
            <a-button type="dashed" style="width: 100%" @click="addDimension">
              <template #icon><PlusOutlined /></template>
              添加评分标准
            </a-button>
          </div>
        </a-form-item>
        <a-form-item label="分数计算" name="calculationRule">
          <a-radio-group
            v-model:value="form.calculationRule"
            style="width: 100%"
          >
            <a-space direction="vertical" :size="8" style="width: 100%">
              <a-radio
                v-for="option in availableCalculationOptions"
                :key="option.value"
                :value="option.value"
                :disabled="option.disabled"
                style="display: block; margin-bottom: 8px"
              >
                {{ option.label }}
              </a-radio>
            </a-space>
          </a-radio-group>
        </a-form-item>
      </a-form>
      <template #footer>
        <a-button style="margin-right: 8px" @click="handleCancel"
          >取消</a-button
        >
        <a-button type="primary" :loading="submitLoading" @click="handleSubmit"
          >确定</a-button
        >
      </template>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from "vue"
import { message } from "ant-design-vue"
import type { FormInstance } from "ant-design-vue"
import {
  SearchOutlined,
  ReloadOutlined,
  PlusOutlined,
  DeleteOutlined,
} from "@ant-design/icons-vue"
import { useListRequest } from "@/composables/useListRequest"
import {
  reviewRulesApi,
  type ReviewRule,
  type QueryReviewRuleParams,
} from "@/api/contests"

// 使用列表请求组合函数
const {
  loading,
  dataSource,
  pagination,
  searchParams,
  fetchList,
  resetSearch,
  search,
  handleTableChange,
} = useListRequest<ReviewRule, QueryReviewRuleParams>({
  requestFn: reviewRulesApi.getList,
  defaultSearchParams: {} as QueryReviewRuleParams,
  defaultPageSize: 10,
  errorMessage: "获取评审规则列表失败",
})

const modalVisible = ref(false)
const submitLoading = ref(false)
const isEditing = ref(false)
const formRef = ref<FormInstance>()
const editingId = ref<number | null>(null)

const form = reactive<{
  ruleName: string
  ruleDescription?: string
  judgeCount?: number
  dimensions: Array<{ name: string; percentage: number; description: string }>
  calculationRule: string
}>({
  ruleName: "",
  ruleDescription: "",
  judgeCount: undefined,
  dimensions: [{ name: "", percentage: 0, description: "" }],
  calculationRule: "average",
})

// 分数计算选项
const calculationOptions = [
  { value: "average", label: "全部均值" },
  { value: "removeMaxMin", label: "去掉一个最高分和一个最低分的均值" },
  { value: "removeMin", label: "去掉最低分的均值" },
]

// 根据评委数量动态计算可用的分数计算选项
const availableCalculationOptions = computed(() => {
  const judgeCount = form.judgeCount || 0
  if (judgeCount === 1) {
    return calculationOptions.map((opt) => ({
      ...opt,
      disabled: opt.value !== "average",
    }))
  } else if (judgeCount === 2) {
    return calculationOptions.map((opt) => ({
      ...opt,
      disabled: opt.value === "removeMin",
    }))
  } else {
    return calculationOptions.map((opt) => ({
      ...opt,
      disabled: false,
    }))
  }
})

// 监听评委数量变化，自动调整分数计算选项
watch(
  () => form.judgeCount,
  (newVal) => {
    if (newVal === 1 && form.calculationRule !== "average") {
      form.calculationRule = "average"
    } else if (newVal === 2 && form.calculationRule === "removeMin") {
      form.calculationRule = "average"
    }
  }
)

const rules = {
  ruleName: [{ required: true, message: "请输入规则名称", trigger: "blur" }],
  judgeCount: [
    { required: true, message: "请输入评委数量", trigger: "change" },
    {
      type: "number",
      min: 1,
      message: "评委数量必须大于等于1",
      trigger: "change",
    },
  ],
  dimensions: [
    {
      validator: (_rule: any, value: any[]) => {
        if (!value || value.length === 0) {
          return Promise.reject("至少添加一个评分标准")
        }
        let totalPercentage = 0
        for (const dim of value) {
          if (!dim.name || !dim.name.trim()) {
            return Promise.reject("评分项名称不能为空")
          }
          if (
            dim.percentage === undefined ||
            dim.percentage === null ||
            dim.percentage < 0
          ) {
            return Promise.reject("分值百分比不能为空且必须大于等于0")
          }
          totalPercentage += dim.percentage || 0
        }
        if (totalPercentage !== 100) {
          return Promise.reject(
            `所有评分项的分值百分比之和必须等于100%，当前为${totalPercentage}%`
          )
        }
        return Promise.resolve()
      },
      trigger: "change",
    },
  ],
  calculationRule: [
    { required: true, message: "请选择分数计算方式", trigger: "change" },
  ],
}

// 表格列定义
const columns = [
  {
    title: "序号",
    key: "index",
    width: 80,
  },
  {
    title: "规则名称",
    dataIndex: "ruleName",
    key: "ruleName",
    width: 200,
  },
  {
    title: "规则描述",
    key: "ruleDescription",
    width: 300,
  },
  {
    title: "关联活动",
    key: "contests",
    width: 200,
  },
  {
    title: "操作",
    key: "action",
    width: 150,
    fixed: "right" as const,
  },
]

// 格式化维度描述
const formatDimensions = (dimensions: any) => {
  if (!dimensions) return "-"
  try {
    const dims =
      typeof dimensions === "string" ? JSON.parse(dimensions) : dimensions
    if (Array.isArray(dims)) {
      return dims
        .map((d: any) => {
          if (d.percentage !== undefined) {
            return `${d.name}(${d.percentage}%)`
          } else if (d.maxScore !== undefined) {
            // 兼容旧数据格式
            return `${d.name}(${d.maxScore}分)`
          }
          return d.name
        })
        .join("、")
    }
    return "-"
  } catch {
    return "-"
  }
}

// 搜索
const handleSearch = () => {
  search()
}

// 重置搜索
const handleReset = () => {
  resetSearch()
}

// 添加评分标准
const addDimension = () => {
  form.dimensions.push({ name: "", percentage: 0, description: "" })
}

// 删除维度
const removeDimension = (index: number) => {
  form.dimensions.splice(index, 1)
}

// 新增
const handleAdd = () => {
  isEditing.value = false
  editingId.value = null
  modalVisible.value = true
  form.ruleName = ""
  form.ruleDescription = ""
  form.judgeCount = undefined
  form.dimensions = [{ name: "", percentage: 0, description: "" }]
  form.calculationRule = "average"
}

// 编辑
const handleEdit = async (record: ReviewRule) => {
  isEditing.value = true
  editingId.value = record.id
  modalVisible.value = true

  try {
    const detail = await reviewRulesApi.getDetail(record.id)
    form.ruleName = detail.ruleName
    form.ruleDescription = detail.ruleDescription || ""
    form.judgeCount = detail.judgeCount || undefined

    // 转换计算规则格式
    let calculationRule = detail.calculationRule || "average"
    if (calculationRule === "remove_max_min") {
      calculationRule = "removeMaxMin"
    } else if (calculationRule === "remove_min") {
      calculationRule = "removeMin"
    }
    form.calculationRule = calculationRule

    // 解析评分标准
    try {
      const dims =
        typeof detail.dimensions === "string"
          ? JSON.parse(detail.dimensions)
          : detail.dimensions
      form.dimensions =
        Array.isArray(dims) && dims.length > 0
          ? dims.map((d: any) => {
              // 兼容旧数据格式
              if (d.percentage !== undefined) {
                return {
                  name: d.name || "",
                  percentage: d.percentage || 0,
                  description: d.description || "",
                }
              } else {
                // 旧格式：maxScore 和 weight，转换为 percentage
                const total = dims.reduce(
                  (sum: number, item: any) => sum + (item.weight || 1),
                  0
                )
                const percentage =
                  total > 0 ? ((d.weight || 1) / total) * 100 : 0
                return {
                  name: d.name || "",
                  percentage: percentage,
                  description: d.description || "",
                }
              }
            })
          : [{ name: "", percentage: 0, description: "" }]
    } catch {
      form.dimensions = [{ name: "", percentage: 0, description: "" }]
    }
  } catch (error) {
    message.error("获取评审规则详情失败")
    modalVisible.value = false
  }
}

// 删除
const handleDelete = async (id: number) => {
  try {
    await reviewRulesApi.delete(id)
    message.success("删除成功")
    fetchList()
  } catch (error: any) {
    message.error(error?.response?.data?.message || "删除失败")
  }
}

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value?.validate()
    submitLoading.value = true

    // 转换分数计算规则
    let calculationRule = form.calculationRule
    if (calculationRule === "removeMaxMin") {
      calculationRule = "remove_max_min"
    } else if (calculationRule === "removeMin") {
      calculationRule = "remove_min"
    }

    const data: any = {
      ruleName: form.ruleName,
      dimensions: form.dimensions,
      calculationRule: calculationRule,
    }

    // 添加可选字段
    if (form.ruleDescription) {
      data.ruleDescription = form.ruleDescription
    }
    if (form.judgeCount !== undefined) {
      data.judgeCount = form.judgeCount
    }

    if (isEditing.value && editingId.value) {
      await reviewRulesApi.update(editingId.value, data)
      message.success("编辑成功")
    } else {
      await reviewRulesApi.create(data)
      message.success("创建成功")
    }

    modalVisible.value = false
    fetchList()
  } catch (error: any) {
    if (error?.errorFields) {
      return
    }
    message.error(
      error?.response?.data?.message ||
        (isEditing.value ? "编辑失败" : "创建失败")
    )
  } finally {
    submitLoading.value = false
  }
}

// 取消
const handleCancel = () => {
  modalVisible.value = false
  formRef.value?.resetFields()
}
</script>

<style scoped lang="scss">
$primary: #1890ff;
$primary-dark: #0958d9;
$gradient-primary: linear-gradient(135deg, $primary 0%, $primary-dark 100%);

.review-rules-page {
  :deep(.ant-card) {
    border: none;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    margin-bottom: 16px;

    .ant-card-head {
      border-bottom: none;
      padding: 16px 24px;

      .ant-card-head-title {
        font-size: 18px;
        font-weight: 600;
        color: rgba(0, 0, 0, 0.85);
      }
    }

    .ant-card-body {
      padding: 0;
    }
  }

  :deep(.ant-btn-primary) {
    background: $gradient-primary;
    border: none;
    box-shadow: 0 4px 12px rgba($primary, 0.35);
    transition: all 0.3s ease;

    &:hover {
      background: linear-gradient(135deg, $primary-dark 0%, darken($primary-dark, 8%) 100%);
      box-shadow: 0 6px 16px rgba($primary, 0.45);
      transform: translateY(-1px);
    }

    &:active {
      transform: translateY(0);
    }
  }

  :deep(.ant-table-wrapper) {
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    overflow: hidden;

    .ant-table {
      .ant-table-thead > tr > th {
        background: #fafafa;
        font-weight: 600;
        color: rgba(0, 0, 0, 0.85);
        border-bottom: 1px solid #f0f0f0;
      }

      .ant-table-tbody > tr {
        transition: all 0.2s ease;

        &:hover > td {
          background: rgba($primary, 0.04);
        }

        > td {
          border-bottom: 1px solid #f5f5f5;
        }
      }
    }

    .ant-table-pagination {
      padding: 16px;
      margin: 0;
    }
  }
}

.search-form {
  margin-bottom: 16px;
  padding: 20px 24px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);

  :deep(.ant-form-item) {
    margin-bottom: 16px;
    margin-right: 16px;

    &:last-child {
      margin-right: 0;
    }
  }
}

.scoring-standards {
  width: 100%;
}

.scoring-standard-item {
  margin-bottom: 16px;
  padding: 16px;
  background: #fafafa;
  border-radius: 4px;
}

.scoring-input-row {
  margin-bottom: 12px;
}
</style>
