<template>
  <div class="step1-basic-info">
    <a-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 16 }"
    >
      <a-form-item label="课程包名称" name="name" required>
        <a-input
          v-model:value="formData.name"
          placeholder="请输入课程包名称"
          show-count
          :maxlength="50"
          @change="handleChange"
        />
      </a-form-item>

      <a-form-item label="关联主题" name="themeId" required>
        <a-select
          v-model:value="formData.themeId"
          placeholder="请选择主题"
          style="width: 100%"
          :loading="themesLoading"
          @change="handleChange"
        >
          <a-select-option v-for="theme in themes" :key="theme.id" :value="theme.id">
            {{ theme.name }}
          </a-select-option>
        </a-select>
      </a-form-item>

      <a-form-item label="适用年级" name="grades" required>
        <a-checkbox-group v-model:value="formData.grades" @change="handleChange">
          <a-checkbox value="小班">小班</a-checkbox>
          <a-checkbox value="中班">中班</a-checkbox>
          <a-checkbox value="大班">大班</a-checkbox>
        </a-checkbox-group>
      </a-form-item>

      <a-form-item label="关联绘本" name="pictureBookName">
        <a-input
          v-model:value="formData.pictureBookName"
          placeholder="请输入关联绘本名称（可选）"
          :maxlength="100"
          @change="handleChange"
        />
      </a-form-item>

      <a-form-item label="核心内容" name="coreContent" required>
        <a-textarea
          v-model:value="formData.coreContent"
          :rows="3"
          placeholder="请输入课程包核心内容概述（200字以内）"
          show-count
          :maxlength="200"
          @change="handleChange"
        />
      </a-form-item>

      <a-form-item label="课程时长" name="duration">
        <a-input-number
          v-model:value="formData.duration"
          :min="5"
          :max="120"
          style="width: 150px"
          @change="handleChange"
        />
        <span class="duration-unit">分钟</span>
      </a-form-item>

      <a-form-item label="核心发展目标" name="domainTags">
        <a-select
          v-model:value="formData.domainTags"
          mode="multiple"
          show-search
          placeholder="请选择核心发展目标（可多选）"
          style="width: 100%"
          :filter-option="filterDomainTagOption"
          @change="handleChange"
        >
          <a-select-opt-group label="健康">
            <a-select-option value="health_motor">身体动作发展</a-select-option>
            <a-select-option value="health_hygiene">生活习惯与能力</a-select-option>
          </a-select-opt-group>
          <a-select-opt-group label="语言">
            <a-select-option value="lang_listen">倾听与表达</a-select-option>
            <a-select-option value="lang_read">早期阅读</a-select-option>
          </a-select-opt-group>
          <a-select-opt-group label="社会">
            <a-select-option value="social_interact">人际交往</a-select-option>
            <a-select-option value="social_adapt">社会适应</a-select-option>
          </a-select-opt-group>
          <a-select-opt-group label="科学">
            <a-select-option value="science_explore">科学探究</a-select-option>
            <a-select-option value="math_cog">数学认知</a-select-option>
          </a-select-opt-group>
          <a-select-opt-group label="艺术">
            <a-select-option value="art_music">音乐表现</a-select-option>
            <a-select-option value="art_create">美术创作</a-select-option>
          </a-select-opt-group>
        </a-select>
      </a-form-item>

      <a-form-item label="课程封面" required>
        <a-upload
          v-model:file-list="coverImages"
          list-type="picture-card"
          :max-count="1"
          accept="image/*"
          :before-upload="beforeCoverUpload"
          @remove="handleCoverRemove"
        >
          <div v-if="coverImages.length < 1">
            <PlusOutlined />
            <div style="margin-top: 8px">上传封面</div>
          </div>
        </a-upload>
        <div class="upload-hint">建议尺寸 400x300，支持 JPG、PNG 格式，最大 5MB</div>
      </a-form-item>
    </a-form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { getThemeList } from '@/api/theme';
import { uploadFile, getFileUrl } from '@/api/file';
import type { Theme } from '@/api/theme';

interface BasicInfoData {
  name: string;
  themeId: number | undefined;
  grades: string[];
  pictureBookName: string;
  coreContent: string;
  duration: number;
  domainTags: string[];
  coverImagePath: string;
}

interface Props {
  modelValue: Partial<BasicInfoData>;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: 'update:modelValue', value: BasicInfoData): void;
  (e: 'change'): void;
}>();

const formRef = ref();
const themesLoading = ref(false);
const themes = ref<Theme[]>([]);
const coverImages = ref<any[]>([]);

/** 核心发展目标：叶子项 + 父级领域名，用于搜索时同时匹配子项与分组 */
const DOMAIN_TAG_OPTIONS: { group: string; value: string; label: string }[] = [
  { group: '健康', value: 'health_motor', label: '身体动作发展' },
  { group: '健康', value: 'health_hygiene', label: '生活习惯与能力' },
  { group: '语言', value: 'lang_listen', label: '倾听与表达' },
  { group: '语言', value: 'lang_read', label: '早期阅读' },
  { group: '社会', value: 'social_interact', label: '人际交往' },
  { group: '社会', value: 'social_adapt', label: '社会适应' },
  { group: '科学', value: 'science_explore', label: '科学探究' },
  { group: '科学', value: 'math_cog', label: '数学认知' },
  { group: '艺术', value: 'art_music', label: '音乐表现' },
  { group: '艺术', value: 'art_create', label: '美术创作' },
];

const filterDomainTagOption = (input: string, option: any) => {
  if (!input?.trim()) return true;
  const q = input.trim();
  const key = option?.value ?? option?.key;
  const row = DOMAIN_TAG_OPTIONS.find((o) => o.value === key);
  if (row) {
    return row.label.includes(q) || row.group.includes(q);
  }
  const label =
    typeof option?.label === 'string'
      ? option.label
      : option?.children?.[0]?.children ?? option?.children;
  if (typeof label === 'string') {
    return label.includes(q);
  }
  return true;
};

const formRules = {
  name: [
    { required: true, message: '请输入课程包名称' },
    { max: 50, message: '课程包名称不能超过50个字' },
    {
      validator: (_: unknown, value: string) => {
        if (value && value.trim().length === 0) {
          return Promise.reject(new Error('请输入课程包名称'));
        }
        return Promise.resolve();
      },
    },
  ],
  themeId: [{ required: true, message: '请选择关联主题' }],
  grades: [
    {
      required: true,
      message: '请至少选择一个适用年级',
      type: 'array',
      min: 1,
    },
  ],
  coreContent: [
    { required: true, message: '请输入核心内容' },
    { max: 200, message: '核心内容不能超过200个字' },
  ],
  duration: [
    { type: 'number' as const, min: 5, max: 120, message: '课程时长需为 5-120 的整数' },
  ],
  pictureBookName: [{ max: 100, message: '关联绘本名称不能超过100个字' }],
};

const formData = reactive<BasicInfoData>({
  name: '',
  themeId: undefined,
  grades: [],
  pictureBookName: '',
  coreContent: '',
  duration: 25,
  domainTags: [],
  coverImagePath: '',
});

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal) {
      Object.assign(formData, newVal);

      // 处理封面图片回显
      if (newVal.coverImagePath) {
        coverImages.value = [{
          uid: '-1',
          name: 'cover',
          status: 'done',
          url: getFileUrl(newVal.coverImagePath),
        }];
      } else {
        coverImages.value = [];
      }
    }
  },
  { immediate: true, deep: true }
);

// 获取主题列表
const fetchThemes = async () => {
  themesLoading.value = true;
  try {
    const res = await getThemeList() as any;
    themes.value = res || [];
  } catch (error) {
    console.error('获取主题列表失败', error);
  } finally {
    themesLoading.value = false;
  }
};

// 封面上传
const beforeCoverUpload = async (file: any) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    message.error('只能上传图片文件');
    return false;
  }

  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isLt5M) {
    message.error('图片大小不能超过 5MB');
    return false;
  }

  try {
    const result = await uploadFile(file, 'cover');
    formData.coverImagePath = result.filePath;
    coverImages.value = [{
      uid: file.uid,
      name: file.name,
      status: 'done',
      url: getFileUrl(result.filePath),
    }];
    handleChange();
    message.success('封面上传成功');
  } catch (error: any) {
    message.error('上传失败: ' + (error.response?.data?.message || error.message));
  }

  return false;
};

const handleCoverRemove = () => {
  coverImages.value = [];
  formData.coverImagePath = '';
  handleChange();
};

// 处理变化
const handleChange = () => {
  emit('update:modelValue', { ...formData });
  emit('change');
};

// 验证
const validate = async () => {
  try {
    await formRef.value?.validate();

    // 校验课程封面
    if (!formData.coverImagePath) {
      return { valid: false, errors: ['请上传课程封面'] };
    }

    return { valid: true, errors: [] as string[] };
  } catch (err: any) {
    const errorFields = err?.errorFields || [];
    const errors = errorFields
      .map((f: any) => f.errors?.[0])
      .filter(Boolean) as string[];
    return { valid: false, errors: errors.length ? errors : ['请完成基本信息'] };
  }
};

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

defineExpose({
  validate,
  formData,
});
</script>

<style scoped lang="scss">
.step1-basic-info {
  .duration-unit {
    margin-left: 8px;
    color: #666;
  }

  .upload-hint {
    margin-top: 8px;
    font-size: 12px;
    color: #999;
  }
}
</style>
