<template>
  <div class="lesson-config-panel">
    <a-form ref="formRef" :model="lessonData" :rules="formRules" :label-col="{ span: 24 }" :wrapper-col="{ span: 24 }"
      layout="vertical">
      <!-- 基本信息 -->
      <a-card size="small" title="基本信息" class="section-card">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="课程名称" name="name">
              <a-input v-model:value="lessonData.name" placeholder="请输入课程名称" @change="handleChange" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="课程时长" name="duration" :extra="`建议 ${minDuration}-${maxDuration} 分钟`">
              <div class="duration-row">
                <a-input-number v-model:value="lessonData.duration" :min="minDuration" :max="maxDuration"
                  class="duration-input" @change="handleChange" />
                <span class="duration-unit">分钟</span>
              </div>
            </a-form-item>
          </a-col>
        </a-row>
        <a-form-item label="课程描述">
          <a-textarea v-model:value="lessonData.description" :rows="2" :maxlength="500" show-count
            placeholder="请输入课程描述（可选）" @change="handleChange" />
        </a-form-item>
      </a-card>

      <!-- 核心资源（导入课/集体课/领域课显示） -->
      <a-card v-if="showResources" size="small" class="section-card">
        <template #title>
          <span>核心资源</span>
        </template>
        <div class="field-hint">按需上传（动画/课件/电子绘本，可选）</div>
        <div class="resource-upload-row">
          <a-row :gutter="16">
            <a-col :span="8">
              <a-form-item label="绘本动画" :name="undefined">
                <FileUploader v-model:file-path="lessonData.videoPath" v-model:file-name="lessonData.videoName"
                  file-type="video" :max-size="200" @change="handleChange" />
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item label="教学课件" :name="undefined">
                <FileUploader v-model:file-path="lessonData.pptPath" v-model:file-name="lessonData.pptName"
                  file-type="ppt" :max-size="100" @change="handleChange" />
              </a-form-item>
            </a-col>
            <a-col :span="8">
              <a-form-item label="电子绘本" :name="undefined">
                <FileUploader v-model:file-path="lessonData.pdfPath" v-model:file-name="lessonData.pdfName"
                  file-type="pdf" :max-size="100" @change="handleChange" />
              </a-form-item>
            </a-col>
          </a-row>
        </div>
      </a-card>

      <!-- 教学目标 & 教学准备 -->
      <a-card size="small" class="section-card">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="教学目标" name="objectives">
              <a-textarea v-model:value="lessonData.objectives" :rows="4" :maxlength="1500" show-count placeholder="请输入教学目标，如：
1. 理解故事主要内容
2. 认识重点词汇
3. 培养阅读兴趣" @change="handleChange" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="教学准备" name="preparation">
              <a-textarea v-model:value="lessonData.preparation" :rows="4" :maxlength="1500" show-count placeholder="请输入教学准备，如：
- 绘本PPT
- 相关图片/视频
- 教具材料" @change="handleChange" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-card>

      <!-- 教学环节 -->
      <a-card size="small" class="section-card">
        <template #title>
          <span>
            教学环节
            <span v-if="lessonType !== 'INTRO'" class="required-mark">*</span>
          </span>
        </template>
        <div class="field-hint">
          <span v-if="lessonType === 'INTRO'">可选配置，可添加教学环节</span>
          <span v-else>至少添加一个环节，每个环节需填写名称、内容、目标</span>
        </div>
        <a-form-item :name="lessonType !== 'INTRO' ? 'steps' : undefined">
          <a-form-item-rest>
            <LessonStepsEditor v-model="lessonData.steps" :show-template="showTemplate" @change="handleChange" />
          </a-form-item-rest>
        </a-form-item>
      </a-card>

      <!-- 教学延伸 & 教学反思（仅集体课/领域课显示） -->
      <a-card v-if="showExtension" size="small" class="section-card">
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="教学延伸" :name="extensionRequired ? 'extension' : undefined"
              :extra="extensionRequired ? '必填（集体课要求）' : '可选'">
              <a-textarea v-model:value="lessonData.extension" :rows="3" :maxlength="1500" show-count
                :placeholder="extensionRequired ? '请输入教学延伸活动建议（必填）' : '请输入教学延伸活动建议（可选）'" @change="handleChange" />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="教学反思">
              <a-textarea v-model:value="lessonData.reflection" :rows="3" :maxlength="1500" show-count
                placeholder="请输入教学反思提示（可选）" @change="handleChange" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-card>

      <!-- 测评工具 -->
      <a-card size="small" title="测评工具" class="section-card">
        <a-form-item label="测评内容">
          <a-textarea v-model:value="lessonData.assessmentData" :rows="3" :maxlength="1500" show-count
            placeholder="请输入测评要点或测评标准（可选）" @change="handleChange" />
        </a-form-item>
      </a-card>
    </a-form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue';
import type { FormInstance } from 'ant-design-vue';
import FileUploader from './FileUploader.vue';
import LessonStepsEditor from './LessonStepsEditor.vue';
import type { StepData } from './LessonStepsEditor.vue';
import { trimFormModel } from '@/utils/trimFormModel';

export interface LessonData {
  id?: number | string;
  tempId?: string;
  lessonType: string;
  name: string;
  description: string;
  duration: number;
  videoPath: string;
  videoName: string;
  pptPath: string;
  pptName: string;
  pdfPath: string;
  pdfName: string;
  objectives: string;
  preparation: string;
  extension: string;
  reflection: string;
  assessmentData: string;
  useTemplate: boolean;
  steps: StepData[];
  isNew?: boolean;
}

interface Props {
  modelValue: Partial<LessonData>;
  lessonType: string;
  minDuration?: number;
  maxDuration?: number;
  showResources?: boolean;
  showExtension?: boolean;
  showTemplate?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => ({}),
  lessonType: 'INTRO',
  minDuration: 5,
  maxDuration: 60,
  showResources: false,
  showExtension: false,
  showTemplate: false,
});

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

// 默认课程数据
const defaultLessonData: LessonData = {
  lessonType: props.lessonType,
  name: '',
  description: '',
  duration: 25,
  videoPath: '',
  videoName: '',
  pptPath: '',
  pptName: '',
  pdfPath: '',
  pdfName: '',
  objectives: '',
  preparation: '',
  extension: '',
  reflection: '',
  assessmentData: '',
  useTemplate: false,
  steps: [],
};

const lessonData = reactive<LessonData>({
  ...defaultLessonData,
  ...props.modelValue,
});

// 教学环节是否必填：集体课、领域课必填，导入课可选
const stepsRequired = computed(
  () => props.lessonType !== 'INTRO'
);

// 教学延伸是否必填：集体课、领域课必填（结构同集体课）
const extensionRequired = computed(
  () => props.lessonType === 'COLLECTIVE' || props.lessonType?.startsWith('DOMAIN_')
);

const formRef = ref<FormInstance>();

// formRules 根据 lessonType 动态生成
const formRules = computed(() => {
  const minD = props.minDuration ?? 5;
  const maxD = props.maxDuration ?? 60;
  const rules: Record<string, any[]> = {
    name: [{ required: true, whitespace: true, message: '请输入课程名称' }],
    objectives: [{ required: true, whitespace: true, message: '请输入教学目标' }],
    preparation: [{ required: true, whitespace: true, message: '请输入教学准备' }],
    duration: [
      { required: true, message: '请输入课程时长' },
      {
        type: 'number' as const,
        min: minD,
        max: maxD,
        message: `课程时长需在 ${minD}-${maxD} 分钟之间`,
      },
    ],
  };
  // 教学环节：集体课/领域课必填，导入课不校验
  if (stepsRequired.value) {
    rules.steps = [
      {
        validator: (_: unknown, value: StepData[] | undefined) => {
          const steps = value || [];
          if (steps.length < 1) {
            return Promise.reject(new Error('请至少添加一个教学环节'));
          }
          for (let i = 0; i < steps.length; i++) {
            const s = steps[i];
            if (!s.name?.trim()) {
              return Promise.reject(new Error(`第${i + 1}个环节：请填写环节名称`));
            }
            if (!s.content?.trim()) {
              return Promise.reject(new Error(`第${i + 1}个环节：请填写环节内容`));
            }
            if (!s.objective?.trim()) {
              return Promise.reject(new Error(`第${i + 1}个环节：请填写教学目标`));
            }
          }
          return Promise.resolve();
        },
      },
    ];
  }
  if (extensionRequired.value) {
    rules.extension = [
      { required: true, whitespace: true, message: '请输入教学延伸活动建议' },
    ];
  }
  return rules;
});

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    Object.assign(lessonData, defaultLessonData, newVal);
  },
  { deep: true }
);

const handleChange = () => {
  emit('update:modelValue', { ...lessonData } as LessonData);
  emit('change');
};

// 表单校验（供 Step4/5/6 调用）
const validate = async () => {
  try {
    // 提交前统一去除首尾空格（仅处理 plain object/array 内字符串）
    trimFormModel(lessonData as any);
    // 同步到父组件 v-model，避免提交仍带空格
    handleChange();
    await formRef.value?.validate();
    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 : ['请完成表单必填项'] };
  }
};

// 暴露方法
defineExpose({
  lessonData,
  formRef,
  validate,
});
</script>

<style scoped lang="scss">
.lesson-config-panel {
  .section-card {
    margin-bottom: 16px;

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

    :deep(.ant-card-head) {
      min-height: 40px;
      padding: 0 12px;

      .ant-card-head-title {
        padding: 8px 0;
        font-size: 14px;
      }
    }

    :deep(.ant-card-body) {
      padding: 16px;
    }
  }

  .duration-unit {
    color: #666;
  }

  .duration-row {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .duration-input {
    flex: 1;
    width: 100%;
  }

  .required-mark {
    color: #ff4d4f;
    margin-left: 2px;
  }

  .optional-tag {
    font-size: 12px;
    color: #8c8c8c;
    margin-left: 4px;
  }

  .field-hint {
    font-size: 12px;
    color: #8c8c8c;
    margin-bottom: 12px;
  }

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

    &:last-child {
      margin-bottom: 0;
    }
  }
}
</style>
