<script lang="ts" setup>
import { computed, h, ref, useTemplateRef } from 'vue';
import type { FormInst, FormRules } from 'naive-ui';
import { NInput, useDialog } from 'naive-ui';
import { client, safeClient } from '@/service/api';
import UploadS3 from '@/components/upload/index.vue';

defineOptions({ name: 'AddNews' });

type Body = CommonType.TreatyBody<typeof client.api.admin.news.post>;

const emit = defineEmits<{
  (e: 'close'): void;
}>();

const formRef = useTemplateRef<FormInst | null>('formRef');
const dialog = useDialog();

const form = ref<Body>({
  title: '',
  content: '',
  categoryId: '',
  attachmentIds: [],
  isPinned: false
});

// 获取分类列表
const { data: categories, execute: refreshCategories } = safeClient(() =>
  client.api.admin.news_categories.get({
    query: {
      pageIndex: 1,
      pageSize: 100
    }
  })
);

const categoryOptions = computed(
  () =>
    categories.value?.data.map(cat => ({
      label: cat.name,
      value: cat.id
    })) || []
);

// 新增分类
function handleAddCategory() {
  const categoryName = ref('');

  dialog.create({
    title: '新增分类',
    content: () =>
      h('div', { class: 'py-4' }, [
        h('div', { class: 'mb-2 text-14px' }, '分类名称'),
        h(NInput, {
          value: categoryName.value,
          placeholder: '请输入分类名称',
          'onUpdate:value': (val: string) => {
            categoryName.value = val;
          }
        })
      ]),
    positiveText: '创建',
    negativeText: '取消',
    onPositiveClick: async () => {
      if (!categoryName.value.trim()) {
        window.$message?.error('请输入分类名称');
        return false;
      }
      const { data } = await safeClient(() =>
        client.api.admin.news_categories.post({
          name: categoryName.value
        })
      );
      if (data) {
        window.$message?.success('分类创建成功');
        await refreshCategories();
        if (data.value?.id) {
          form.value.categoryId = data.value.id;
        }
      }
    }
  });
}

const rules: FormRules = {
  title: [
    {
      required: true,
      message: '请输入新闻标题',
      trigger: ['blur', 'input']
    },
    {
      min: 2,
      max: 200,
      message: '标题长度应在2-200个字符之间',
      trigger: ['blur', 'input']
    }
  ],
  summary: [
    {
      required: true,
      message: '请输入新闻摘要',
      trigger: ['blur', 'input']
    },
    {
      min: 10,
      max: 200,
      message: '摘要长度应在10-200个字符之间',
      trigger: ['blur', 'input']
    }
  ],
  content: [
    {
      required: true,
      message: '请输入新闻内容',
      trigger: ['blur', 'input']
    },
    {
      min: 10,
      message: '内容至少10个字符',
      trigger: ['blur', 'input']
    }
  ],
  categoryId: [
    {
      required: true,
      message: '请选择新闻分类',
      trigger: 'change'
    }
  ]
};

async function handleSubmit() {
  formRef.value?.validate(async errors => {
    if (!errors) {
      const { data } = await safeClient(() =>
        client.api.admin.news.post({
          ...form.value
        })
      );
      if (data) {
        window.$message?.success('新闻创建成功');
        emit('close');
      }
    }
  });
}
</script>

<template>
  <NForm
    ref="formRef"
    :model="form"
    :rules="rules"
    label-width="100px"
    label-placement="left"
    require-mark-placement="left"
  >
    <NFormItem label="新闻标题" path="title">
      <NInput v-model:value="form.title" placeholder="请输入新闻标题" maxlength="50" show-count />
    </NFormItem>

    <NFormItem label="缩略图" path="thumbnailId">
      <UploadS3
        :model-value="form.thumbnailId ? [form.thumbnailId] : undefined"
        :max-size="20"
        :max-files="1"
        accept="image/*"
        placeholder="上传图片"
        :fetch-options="{ businessType: 'news_attachment' }"
        @update:model-value="evt => (form.thumbnailId = evt.length > 0 ? evt[0] : undefined)"
      />
    </NFormItem>

    <NGrid :cols="2">
      <NFormItemGi label="新闻分类" path="categoryId">
        <NSelect v-model:value="form.categoryId" :options="categoryOptions" placeholder="请选择新闻分类" class="flex-1">
          <template #action>
            <div class="px-3 py-2">
              <NButton size="small" type="primary" block @click.stop="handleAddCategory">
                <template #icon>
                  <icon-ic-round-plus class="text-icon" />
                </template>
                新增分类
              </NButton>
            </div>
          </template>
        </NSelect>
      </NFormItemGi>

      <NFormItemGi label="新闻摘要" path="summary">
        <NInput v-model:value="form.summary" placeholder="请输入新闻摘要" maxlength="100" show-count />
      </NFormItemGi>
    </NGrid>

    <NFormItem label="新闻内容" path="content">
      <MarkdownEditor v-model:value="form.content" placeholder="请输入新闻内容" :preview="false" />
    </NFormItem>

    <NFormItem label="附件上传" path="attachmentIds">
      <UploadS3
        :model-value="form.attachmentIds || []"
        :max-size="20"
        :max-files="10"
        accept="*/*"
        placeholder="上传附件"
        :fetch-options="{ businessType: 'other' }"
        @update:model-value="evt => (form.attachmentIds = evt)"
      />
    </NFormItem>

    <NGrid :cols="2">
      <NFormItemGi label="置顶显示" path="isPinned">
        <NSwitch v-model:value="form.isPinned">
          <template #checked>是</template>
          <template #unchecked>否</template>
        </NSwitch>
      </NFormItemGi>

      <NFormItemGi label="排序顺序" path="sortOrder">
        <NInputNumber v-model:value="form.sortOrder" :min="0" :step="1" placeholder="请输入排序顺序" class="w-full">
          <template #suffix>
            <span class="text-12px text-gray-400">数字越小越靠前</span>
          </template>
        </NInputNumber>
      </NFormItemGi>
    </NGrid>

    <NSpace justify="end" class="mt-4">
      <NButton @click="$emit('close')">取消</NButton>
      <NButton type="primary" @click="handleSubmit">创建新闻</NButton>
    </NSpace>
  </NForm>
</template>

<style lang="css" scoped></style>
