<template>
  <div class="create-contest-page">
    <a-spin :spinning="pageLoading">
      <!-- 顶部导航 -->
      <div class="page-header">
        <a-button type="text" @click="handleCancel" style="padding: 0; margin-right: 8px">
          <template #icon><ArrowLeftOutlined /></template>
        </a-button>
        <a-breadcrumb>
          <a-breadcrumb-item><router-link :to="`/${tenantCode}/contests`">活动管理</router-link></a-breadcrumb-item>
          <a-breadcrumb-item>{{ isEdit ? '编辑活动' : '创建活动' }}</a-breadcrumb-item>
        </a-breadcrumb>
      </div>

      <a-form ref="formRef" :model="form" :rules="rules" layout="vertical" class="contest-form">
        <!-- 主办信息 -->
        <div class="form-section">
          <h3 class="section-title">主办信息</h3>
          <a-row :gutter="24">
            <a-col :span="24">
              <a-form-item label="主办单位" name="organizers" required>
                <a-input v-model:value="form.organizers" placeholder="请输入主办单位" :maxlength="200" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="协办单位" name="coOrganizers">
                <a-input v-model:value="form.coOrganizers" placeholder="请输入协办单位" :maxlength="200" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="赞助单位" name="sponsors">
                <a-input v-model:value="form.sponsors" placeholder="请输入赞助单位" :maxlength="200" />
              </a-form-item>
            </a-col>
          </a-row>
        </div>

        <!-- 活动信息 -->
        <div class="form-section">
          <h3 class="section-title">活动信息</h3>
          <a-row :gutter="24">
            <a-col :span="24">
              <a-form-item label="活动名称" name="contestName" required>
                <a-input v-model:value="form.contestName" placeholder="请输入活动名称" :maxlength="200" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="活动类型" name="contestType" required>
                <a-select v-model:value="form.contestType" placeholder="请选择活动类型">
                  <a-select-option value="individual">个人参与</a-select-option>
                  <a-select-option value="team">团队参与</a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="活动时间" name="timeRange" required>
                <a-range-picker v-model:value="timeRange" show-time format="YYYY-MM-DD HH:mm" style="width: 100%" @change="handleTimeRangeChange" />
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item label="可见范围" name="visibility">
                <a-radio-group v-model:value="form.visibility">
                  <a-radio value="public">公开（所有公众用户可见）</a-radio>
                  <a-radio value="targeted">定向推送（按城市/年龄筛选）</a-radio>
                  <a-radio value="designated">指定机构</a-radio>
                  <a-radio value="internal">仅内部</a-radio>
                </a-radio-group>
              </a-form-item>
            </a-col>
            <a-col v-if="form.visibility === 'targeted'" :span="12">
              <a-form-item label="目标城市">
                <a-select v-model:value="form.targetCities" mode="tags" placeholder="输入城市名称后按回车添加" />
                <div class="form-hint">留空表示不限城市</div>
              </a-form-item>
            </a-col>
            <a-col v-if="form.visibility === 'public' || form.visibility === 'targeted'" :span="12">
              <a-form-item label="年龄限制">
                <a-space>
                  <a-input-number v-model:value="form.ageMin" :min="1" :max="99" placeholder="最小" style="width: 100px" />
                  <span>至</span>
                  <a-input-number v-model:value="form.ageMax" :min="1" :max="99" placeholder="最大" style="width: 100px" />
                  <span class="form-hint">岁（留空不限）</span>
                </a-space>
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item label="活动详情" name="content" required>
                <RichTextEditor v-model="form.content" placeholder="请输入活动详细说明" :height="300" />
              </a-form-item>
            </a-col>
          </a-row>
        </div>

        <!-- 图片与附件 -->
        <div class="form-section">
          <h3 class="section-title">图片与附件</h3>
          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="活动封面" name="coverUrl" required>
                <a-upload v-model:file-list="coverFileList" list-type="picture-card" :before-upload="beforeUpload"
                  :custom-request="handleCoverUpload" accept="image/*" :max-count="1">
                  <div v-if="coverFileList.length < 1">
                    <plus-outlined />
                    <div style="margin-top: 8px">上传封面</div>
                  </div>
                </a-upload>
                <div class="form-hint">建议尺寸 16:9，小于 30M</div>
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="活动海报" name="posterUrl" required>
                <a-upload v-model:file-list="posterFileList" list-type="picture-card" :before-upload="beforeUpload"
                  :custom-request="handlePosterUpload" accept="image/*" :max-count="1">
                  <div v-if="posterFileList.length < 1">
                    <plus-outlined />
                    <div style="margin-top: 8px">上传海报</div>
                  </div>
                </a-upload>
                <div class="form-hint">建议尺寸 16:9，小于 30M</div>
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item label="活动附件" name="attachments">
                <a-upload v-model:file-list="attachmentFileList" :before-upload="beforeFileUpload"
                  :custom-request="handleAttachmentUpload" :max-count="10">
                  <a-button><upload-outlined /> 上传附件</a-button>
                </a-upload>
                <div class="form-hint">最多 10 个文件，每个不超过 30M</div>
              </a-form-item>
            </a-col>
          </a-row>
        </div>

        <!-- 时间配置 -->
        <div class="form-section">
          <h3 class="section-title">时间配置</h3>
          <a-row :gutter="24">
            <a-col :span="12">
              <a-form-item label="报名时间" name="registerTimeRange" required>
                <a-range-picker v-model:value="registerTimeRange" show-time format="YYYY-MM-DD HH:mm" style="width: 100%"
                  :disabled-date="disabledRegisterDate" @change="handleRegisterTimeRangeChange" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="提交规则" name="submitRule" required>
                <a-radio-group v-model:value="form.submitRule">
                  <a-radio value="once">仅允许提交一次</a-radio>
                  <a-radio value="resubmit">允许重复提交</a-radio>
                </a-radio-group>
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="作品提交时间" name="submitTimeRange" required>
                <a-range-picker v-model:value="submitTimeRange" show-time format="YYYY-MM-DD HH:mm" style="width: 100%"
                  :disabled-date="disabledSubmitDate" @change="handleSubmitTimeRangeChange" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="评审规则" name="reviewRuleId">
                <a-select v-model:value="form.reviewRuleId" placeholder="请选择评审规则（可选）" :options="reviewRuleOptions" allow-clear />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="评审时间" name="reviewTimeRange" required>
                <a-range-picker v-model:value="reviewTimeRange" show-time format="YYYY-MM-DD HH:mm" style="width: 100%"
                  :disabled-date="disabledReviewDate" @change="handleReviewTimeRangeChange" />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="结果公布时间" name="resultPublishTime">
                <a-date-picker v-model:value="resultPublishTime" show-time format="YYYY-MM-DD HH:mm" style="width: 100%"
                  :disabled-date="disabledPublishDate" placeholder="请选择结果公布时间" @change="handleResultPublishTimeChange" />
              </a-form-item>
            </a-col>
          </a-row>
        </div>

        <!-- 底部操作按钮 -->
        <div class="form-actions">
          <a-button @click="handleCancel">取消</a-button>
          <a-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</a-button>
        </div>
      </a-form>
    </a-spin>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, nextTick, onMounted, computed } from "vue"
import { useRouter, useRoute } from "vue-router"
import { message } from "ant-design-vue"
import type { FormInstance, UploadFile } from "ant-design-vue"
import type { Dayjs } from "dayjs"
import dayjs from "dayjs"
import { PlusOutlined, UploadOutlined, ArrowLeftOutlined } from "@ant-design/icons-vue"
import RichTextEditor from "@/components/RichTextEditor.vue"
import { contestsApi, attachmentsApi, reviewRulesApi, type CreateContestForm, type Contest } from "@/api/contests"
import { uploadFile } from "@/api/upload"

const router = useRouter()
const route = useRoute()
const tenantCode = route.params.tenantCode as string

const contestId = computed(() => route.params.id ? Number(route.params.id) : null)
const isEdit = computed(() => !!contestId.value)
const pageLoading = ref(false)
const formRef = ref<FormInstance>()
const submitLoading = ref(false)

const form = reactive<CreateContestForm & { reviewRuleId?: number }>({
  contestName: "", contestType: "individual", visibility: "designated",
  targetCities: [] as string[], ageMin: undefined as number | undefined, ageMax: undefined as number | undefined,
  startTime: "", endTime: "", content: "", coverUrl: "", posterUrl: "",
  organizers: "", coOrganizers: "", sponsors: "",
  registerStartTime: "", registerEndTime: "",
  submitRule: "once", submitStartTime: "", submitEndTime: "",
  reviewStartTime: "", reviewEndTime: "", resultPublishTime: "",
})

const timeRange = ref<[Dayjs, Dayjs] | null>(null)
const registerTimeRange = ref<[Dayjs, Dayjs] | null>(null)
const submitTimeRange = ref<[Dayjs, Dayjs] | null>(null)
const reviewTimeRange = ref<[Dayjs, Dayjs] | null>(null)
const resultPublishTime = ref<Dayjs | null>(null)

const coverFileList = ref<UploadFile[]>([])
const posterFileList = ref<UploadFile[]>([])
const attachmentFileList = ref<UploadFile[]>([])
const reviewRuleOptions = ref<{ value: number; label: string }[]>([])

const fetchReviewRules = async () => {
  try {
    const rules = await reviewRulesApi.getForSelect()
    reviewRuleOptions.value = rules.map(r => ({ value: r.id, label: r.ruleName }))
  } catch { /* */ }
}

const rules = {
  contestName: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
  contestType: [{ required: true, message: "请选择活动类型", trigger: "change" }],
  organizers: [{ required: true, message: "请输入主办单位", trigger: "change" }],
  content: [{ required: true, message: "请输入活动详情", trigger: "blur" }],
  coverUrl: [{ required: true, message: "请上传活动封面", trigger: "change" }],
  posterUrl: [{ required: true, message: "请上传活动海报", trigger: "change" }],
  timeRange: [{ required: true, validator: () => (!timeRange.value || !form.startTime || !form.endTime) ? Promise.reject("请选择活动时间") : Promise.resolve(), trigger: "change" }],
  registerTimeRange: [{ required: true, validator: () => (!registerTimeRange.value || !form.registerStartTime || !form.registerEndTime) ? Promise.reject("请选择报名时间") : Promise.resolve(), trigger: "change" }],
  submitRule: [{ required: true, message: "请选择提交规则", trigger: "change" }],
  submitTimeRange: [{ required: true, validator: () => (!submitTimeRange.value || !form.submitStartTime || !form.submitEndTime) ? Promise.reject("请选择提交时间") : Promise.resolve(), trigger: "change" }],
  reviewTimeRange: [{ required: true, validator: () => (!reviewTimeRange.value || !form.reviewStartTime || !form.reviewEndTime) ? Promise.reject("请选择评审时间") : Promise.resolve(), trigger: "change" }],
}

const beforeUpload = (file: File) => {
  const isImage = file.type.startsWith("image/")
  if (!isImage) { message.error("只能上传图片文件！"); return false }
  const isLt30M = file.size / 1024 / 1024 < 30
  if (!isLt30M) { message.error("图片大小不能超过30M！"); return false }
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const img = new Image()
      img.onload = () => {
        const ratio = img.width / img.height
        if (Math.abs(ratio - 16 / 9) > 0.1) message.warning("图片尺寸建议为16:9")
        resolve(true)
      }
      img.src = e.target?.result as string
    }
    reader.readAsDataURL(file)
  })
}

const beforeFileUpload = (file: File) => {
  if (file.size / 1024 / 1024 >= 30) { message.error("文件大小不能超过30M！"); return false }
  return true
}

const handleCoverUpload = async (options: any) => {
  const { file, onSuccess, onError } = options
  try {
    const result: any = await uploadFile(file)
    const url = result.data?.url || result.url
    if (url) { form.coverUrl = url; onSuccess(); message.success("封面上传成功") }
    else throw new Error("无法获取图片地址")
  } catch (e: any) { onError(e); message.error(e?.response?.data?.message || "封面上传失败") }
}

const handlePosterUpload = async (options: any) => {
  const { file, onSuccess, onError } = options
  try {
    const result: any = await uploadFile(file)
    const url = result.data?.url || result.url
    if (url) { form.posterUrl = url; onSuccess(); message.success("海报上传成功") }
    else throw new Error("无法获取图片地址")
  } catch (e: any) { onError(e); message.error(e?.response?.data?.message || "海报上传失败") }
}

const handleAttachmentUpload = async (options: any) => {
  const { file, onSuccess, onError } = options
  try {
    const result: any = await uploadFile(file)
    const url = result.data?.url || result.url
    if (url) {
      await nextTick()
      const idx = attachmentFileList.value.findIndex(f => f.uid === file.uid || f.name === file.name)
      if (idx !== -1) {
        attachmentFileList.value[idx] = { ...attachmentFileList.value[idx], url, response: result, status: "done" }
      } else {
        attachmentFileList.value.push({ uid: file.uid, name: file.name, status: "done", url, response: result })
      }
      onSuccess(); message.success("附件上传成功")
    } else throw new Error("无法获取文件地址")
  } catch (e: any) {
    const idx = attachmentFileList.value.findIndex(f => f.uid === file.uid || f.name === file.name)
    if (idx !== -1) attachmentFileList.value[idx].status = "error"
    onError(e); message.error(e?.response?.data?.message || "附件上传失败")
  }
}

const handleTimeRangeChange = (dates: [Dayjs, Dayjs] | null) => {
  if (dates?.length === 2) { form.startTime = dates[0].format("YYYY-MM-DD HH:mm:ss"); form.endTime = dates[1].format("YYYY-MM-DD HH:mm:ss") }
  else { form.startTime = ""; form.endTime = "" }
  formRef.value?.validateFields(["timeRange"])
}
const handleRegisterTimeRangeChange = (dates: [Dayjs, Dayjs] | null) => {
  if (dates?.length === 2) { form.registerStartTime = dates[0].format("YYYY-MM-DD HH:mm:ss"); form.registerEndTime = dates[1].format("YYYY-MM-DD HH:mm:ss") }
  else { form.registerStartTime = ""; form.registerEndTime = "" }
  formRef.value?.validateFields(["registerTimeRange"])
}
const handleSubmitTimeRangeChange = (dates: [Dayjs, Dayjs] | null) => {
  if (dates?.length === 2) { form.submitStartTime = dates[0].format("YYYY-MM-DD HH:mm:ss"); form.submitEndTime = dates[1].format("YYYY-MM-DD HH:mm:ss") }
  else { form.submitStartTime = ""; form.submitEndTime = "" }
  formRef.value?.validateFields(["submitTimeRange"])
}
const handleReviewTimeRangeChange = (dates: [Dayjs, Dayjs] | null) => {
  if (dates?.length === 2) { form.reviewStartTime = dates[0].format("YYYY-MM-DD HH:mm:ss"); form.reviewEndTime = dates[1].format("YYYY-MM-DD HH:mm:ss") }
  else { form.reviewStartTime = ""; form.reviewEndTime = "" }
  formRef.value?.validateFields(["reviewTimeRange"])
}
const handleResultPublishTimeChange = (date: Dayjs | null) => {
  form.resultPublishTime = date ? date.format("YYYY-MM-DD HH:mm:ss") : ""
}

const disabledRegisterDate = (current: Dayjs | null) => {
  if (!timeRange.value || !current) return false
  return current < timeRange.value[0].startOf("day") || current > timeRange.value[1].endOf("day")
}
const disabledSubmitDate = (current: Dayjs | null) => {
  if (!registerTimeRange.value || !timeRange.value || !current) return false
  return current < registerTimeRange.value[1].startOf("day") || current > timeRange.value[1].endOf("day")
}
const disabledReviewDate = (current: Dayjs | null) => {
  if (!registerTimeRange.value || !timeRange.value || !current) return false
  return current < registerTimeRange.value[1].startOf("day") || current > timeRange.value[1].endOf("day")
}
const disabledPublishDate = (current: Dayjs | null) => {
  if (!reviewTimeRange.value || !timeRange.value || !current) return false
  return current < reviewTimeRange.value[1].startOf("day") || current > timeRange.value[1].endOf("day")
}

const loadContestData = async () => {
  if (!contestId.value) return
  pageLoading.value = true
  try {
    const c = await contestsApi.getDetail(contestId.value)
    form.contestName = c.contestName || ""
    form.contestType = c.contestType || "individual"
    form.startTime = c.startTime || ""
    form.endTime = c.endTime || ""
    form.content = c.content || ""
    form.coverUrl = c.coverUrl || ""
    form.posterUrl = c.posterUrl || ""
    form.organizers = Array.isArray(c.organizers) ? c.organizers.join("、") : c.organizers || ""
    form.coOrganizers = Array.isArray(c.coOrganizers) ? c.coOrganizers.join("、") : c.coOrganizers || ""
    form.sponsors = Array.isArray(c.sponsors) ? c.sponsors.join("、") : c.sponsors || ""
    form.registerStartTime = c.registerStartTime || ""
    form.registerEndTime = c.registerEndTime || ""
    form.submitRule = c.submitRule || "once"
    form.submitStartTime = c.submitStartTime || ""
    form.submitEndTime = c.submitEndTime || ""
    form.reviewRuleId = c.reviewRuleId || undefined
    form.reviewStartTime = c.reviewStartTime || ""
    form.reviewEndTime = c.reviewEndTime || ""
    form.resultPublishTime = c.resultPublishTime || ""

    if (c.startTime && c.endTime) timeRange.value = [dayjs(c.startTime), dayjs(c.endTime)]
    if (c.registerStartTime && c.registerEndTime) registerTimeRange.value = [dayjs(c.registerStartTime), dayjs(c.registerEndTime)]
    if (c.submitStartTime && c.submitEndTime) submitTimeRange.value = [dayjs(c.submitStartTime), dayjs(c.submitEndTime)]
    if (c.reviewStartTime && c.reviewEndTime) reviewTimeRange.value = [dayjs(c.reviewStartTime), dayjs(c.reviewEndTime)]
    if (c.resultPublishTime) resultPublishTime.value = dayjs(c.resultPublishTime)

    if (c.coverUrl) coverFileList.value = [{ uid: "-1", name: "cover", status: "done", url: c.coverUrl }]
    if (c.posterUrl) posterFileList.value = [{ uid: "-2", name: "poster", status: "done", url: c.posterUrl }]
    if (c.attachments?.length) {
      attachmentFileList.value = c.attachments.map((att: any, i: number) => ({ uid: `-${i + 3}`, name: att.fileName, status: "done", url: att.fileUrl }))
    }
  } catch (e: any) { message.error(e?.response?.data?.message || "加载活动数据失败"); router.back() }
  finally { pageLoading.value = false }
}

const handleSubmit = async () => {
  try {
    await formRef.value?.validate()
    submitLoading.value = true

    const submitData: CreateContestForm = {
      contestName: form.contestName, contestType: form.contestType, startTime: form.startTime, endTime: form.endTime,
      content: form.content, coverUrl: form.coverUrl, posterUrl: form.posterUrl,
      organizers: form.organizers, coOrganizers: form.coOrganizers, sponsors: form.sponsors,
      registerStartTime: form.registerStartTime, registerEndTime: form.registerEndTime,
      submitRule: form.submitRule, submitStartTime: form.submitStartTime, submitEndTime: form.submitEndTime,
      reviewRuleId: form.reviewRuleId || undefined,
      reviewStartTime: form.reviewStartTime, reviewEndTime: form.reviewEndTime,
      resultPublishTime: form.resultPublishTime || undefined,
    }

    if (isEdit.value && contestId.value) {
      await contestsApi.update(contestId.value, submitData)
      message.success("保存成功")
    } else {
      const contest = await contestsApi.create(submitData)
      if (attachmentFileList.value.length > 0) {
        try {
          await Promise.all(attachmentFileList.value.map(file => {
            const fileUrl = file.url || file.response?.url || file.response?.data?.url
            if (fileUrl && file.name) {
              return attachmentsApi.create({ contestId: contest.id, fileName: file.name, fileUrl, format: file.name.split(".").pop()?.toLowerCase(), size: file.size?.toString() })
            }
            return Promise.resolve()
          }))
        } catch { message.warning("活动创建成功，但部分附件记录创建失败") }
      }
      message.success("创建成功")
    }
    router.push(`/${tenantCode}/contests/list`)
  } catch (e: any) {
    if (e?.errorFields) return
    message.error(e?.response?.data?.message || (isEdit.value ? "保存失败" : "创建失败"))
  } finally { submitLoading.value = false }
}

const handleCancel = () => { router.back() }

onMounted(() => {
  fetchReviewRules()
  if (isEdit.value) loadContestData()
})
</script>

<style scoped lang="scss">
$primary: #6366f1;

.create-contest-page {
  max-width: 960px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.contest-form {
  :deep(.ant-form-item-label > label) {
    font-weight: 500;
    color: #374151;
  }
}

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

  .section-title {
    font-size: 16px;
    font-weight: 600;
    color: #1e1b4b;
    margin: 0 0 20px;
    padding-bottom: 12px;
    border-bottom: 1px solid #f0ecf9;
  }
}

.form-hint {
  font-size: 12px;
  color: #9ca3af;
  margin-top: 4px;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 20px 24px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}
</style>
