<template>
  <div class="train-form bg-white p-6 rounded h-full overflow-y-auto">
    <div class="form-breadcrumb mb-4 text-gray-400 text-xs">
      课程管理 / 培训课程 / {{ initialData ? '编辑' : '新增' }}{{ type === 'video' ? '视频' : type === 'live' ? '直播' : '线下' }}培训
    </div>
    <div class="form-header mb-8">
      <div class="text-xl font-bold">{{ initialData ? '编辑' : '新增' }}{{ type === 'video' ? '视频培训' : type === 'live' ? '直播培训' : '线下培训' }}</div>
    </div>

    <div class="form-wrapper border-2 border-blue-500 rounded-lg p-10 bg-white relative">
      <div class="section-title font-bold mb-8 text-base">基础信息</div>
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
        label-position="right"
      >
        <el-form-item label="培训名称" prop="name" required>
          <el-input v-model="form.name" placeholder="请输入培训名称" style="width: 400px" />
        </el-form-item>

        <template v-if="type === 'video'">
          <el-form-item label="培训封面" prop="thumbnail" required>
            <div class="thumbnail-uploader">
              <input
                ref="thumbnailInputRef"
                type="file"
                accept=".jpg,.jpeg,.png"
                class="hidden"
                @change="handleThumbnailFileChange"
              />
              <el-upload
                ref="thumbnailUploadRef"
                class="avatar-uploader"
                action="#"
                :auto-upload="false"
                :show-file-list="false"
                accept=".jpg,.jpeg,.png"
                @click="handleUploadThumbnail"
              >
                <img v-if="form.thumbnailUrl" :src="form.thumbnailUrl" class="avatar-preview" />
                <el-icon v-else class="avatar-uploader-icon"><i-ep-plus /></el-icon>
              </el-upload>
              <div class="upload-hint text-gray-400 text-xs mt-2">
                建议尺寸640*320，小于10M的JPG、PNG格式图片
              </div>
            </div>
          </el-form-item>

          <el-form-item label="课程描述" prop="description">
            <el-input
              v-model="form.description"
              type="textarea"
              :rows="4"
              placeholder="从零开始学西班牙语，直达欧标B2水平！"
              style="width: 500px"
            />
          </el-form-item>

          <el-form-item label="课程类型" prop="videoList">
            <input
              ref="videoInputRef"
              type="file"
              accept=".mp4,.avi,.wmv,.mov,.flv,.rmvb,.3gp,.m4v,.mkv"
              class="hidden"
              @change="handleVideoFileChange"
            />
            <el-button type="primary" size="small" :loading="videoUploading" @click="handleUploadVideo">
              <el-icon class="mr-1"><i-ep-plus /></el-icon>
              上传视频
            </el-button>
            <div class="upload-hint text-gray-400 text-xs mt-1 mb-2">
              支持mp4、avi、wmv、mov、flv、rmvb、3gp、m4v、mkv格式；单个文件最大不超过10G
            </div>
            <el-table :data="form.videoList" size="small" class="video-table mt-2 border">
              <el-table-column label="视频信息" prop="name" min-width="150">
                <template #default="scope">
                  <div class="flex items-center">
                    <el-icon class="mr-2 text-blue-500"><i-ep-video-play /></el-icon>
                    <span class="text-blue-500 underline cursor-pointer">{{ scope.row.name }}</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="视频大小" prop="fileSize" width="100" />
              <el-table-column label="视频类型" prop="fileType" width="80" />
              <el-table-column label="视频时长" prop="duration" width="100" />
              <el-table-column label="操作" width="80" align="center">
                <template #default="scope">
                  <el-link type="primary" :underline="false" @click="removeVideo(scope.$index)">删除</el-link>
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </template>

        <template v-else-if="type === 'offline'">
          <el-form-item label="培训描述" prop="description">
            <el-input
              v-model="form.description"
              type="textarea"
              :rows="4"
              placeholder="从零开始学西班牙语，直达欧标B2水平！"
              style="width: 500px"
            />
          </el-form-item>
        </template>

        <div class="flex flex-wrap items-center">
          <el-form-item label="岗位级别" prop="jobLevel" required>
            <el-select v-model="form.jobLevel" placeholder="请选择" style="width: 180px">
              <el-option
                v-for="item in jobLevelOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="岗位" prop="job" class="ml-4">
            <el-select v-model="form.job" placeholder="请选择" style="width: 180px" filterable>
              <el-option
                v-for="item in jobOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </div>

        <el-form-item label="岗位类型" prop="jobType" required>
          <el-select v-model="form.jobType" placeholder="全职" style="width: 180px">
            <el-option
              v-for="item in jobTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <template v-if="type === 'video'">
          <el-form-item label="排序号" prop="sortOrder">
            <el-input v-model="form.sortOrder" placeholder="请输入" style="width: 320px" />
          </el-form-item>
        </template>

        <template v-if="type === 'offline'">
          <el-form-item label="培训地址" prop="addressDetail" required>
            <div class="address-container">
              <el-cascader
                v-model="form.region"
                :options="regionOptions"
                :props="regionProps"
                clearable
                placeholder="省 / 市 / 区"
                class="region-cascader"
              />
              <el-input v-model="form.addressDetail" placeholder="请输入具体地址" class="address-detail-input" />
            </div>
          </el-form-item>

          <el-form-item label="培训时间" prop="timeRange" required>
            <el-date-picker
              v-model="form.timeRange"
              type="datetimerange"
              range-separator="-"
              start-placeholder="YYYY-MM-DD HH:mm:ss"
              end-placeholder="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 400px"
            />
          </el-form-item>

          <el-form-item label="报名时间" prop="applyRange" required>
            <el-date-picker
              v-model="form.applyRange"
              type="datetimerange"
              range-separator="-"
              start-placeholder="YYYY-MM-DD HH:mm:ss"
              end-placeholder="YYYY-MM-DD HH:mm:ss"
              value-format="YYYY-MM-DD HH:mm:ss"
              style="width: 400px"
            />
          </el-form-item>

          <el-form-item label="主办单位" prop="organizer">
            <el-input v-model="form.organizer" placeholder="主办单位AAAAA" style="width: 320px" />
          </el-form-item>

          <el-form-item label="标签" prop="tags">
            <div class="flex items-center gap-2">
              <el-tag
                v-for="tag in tagList"
                :key="tag"
                closable
                @close="handleCloseTag(tag)"
              >
                {{ tag }}
              </el-tag>
              <el-input
                v-if="inputTagVisible"
                ref="inputTagRef"
                v-model="inputTagValue"
                size="small"
                style="width: 80px"
                @keyup.enter="handleInputTagConfirm"
                @blur="handleInputTagConfirm"
              />
              <el-button v-else size="small" @click="showInputTag">
                <el-icon><i-ep-plus /></el-icon>
                标签
              </el-button>
            </div>
          </el-form-item>
        </template>

        <div class="flex gap-6 mt-12">
          <el-button type="primary" class="submit-btn" @click="handleSubmit">提交</el-button>
          <el-button class="back-btn" @click="$emit('cancel')">返回</el-button>
        </div>
      </el-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import { regionData } from 'element-china-area-data';
import type { FormInstance, FormRules, UploadInstance } from 'element-plus';
import { uploadTrainingFile } from '../../../api/main/training/index';
import { listPosition } from '../../../api/main/position/index';
import { getDicts } from '../../../api/system/dict/data/index';

const props = defineProps<{
  initialData?: any;
  type: string;
}>();

const emit = defineEmits(['cancel', 'submit']);

const formRef = ref<FormInstance>();
const form = reactive({
  id: undefined as any,
  name: '',
  thumbnail: undefined as any,
  thumbnailUrl: '',
  description: '',
  videoList: [] as any[],
  jobLevel: '',
  job: '',
  jobType: '',
  sortOrder: '',
  city: '上海市',
  area: '黄浦区',
  region: ['上海市', '上海市', '黄浦区'] as string[],
  addressDetail: '',
  timeRange: [] as string[],
  applyRange: [] as string[],
  organizer: '',
  tags: '',
  status: 1
});

/** 将 element-china-area-data 的数字编码转为文字作为 value */
const convertRegionToLabelValue = (data: any[]): any[] => {
  return data.map(item => ({
    value: item.label,
    label: item.label,
    children: item.children ? convertRegionToLabelValue(item.children) : undefined
  }));
};

const regionOptions = convertRegionToLabelValue(regionData);

const regionProps = {
  checkStrictly: false,
  emitPath: true
};

/** 标签列表（从逗号分隔字符串解析） */
const tagList = computed({
  get: () => form.tags ? form.tags.split(',').filter(Boolean) : [],
  set: (val: string[]) => { form.tags = val.join(','); }
});

const inputTagVisible = ref(false);
const inputTagValue = ref('');
const inputTagRef = ref();
const thumbnailInputRef = ref<HTMLInputElement>();
const thumbnailUploadRef = ref<UploadInstance>();
const videoInputRef = ref<HTMLInputElement>();
const thumbnailUploading = ref(false);
const videoUploading = ref(false);
const jobLevelOptions = ref<{ label: string; value: string }[]>([]);
const jobTypeOptions = ref<{ label: string; value: string }[]>([]);
const jobOptions = ref<{ label: string; value: string }[]>([]);

const rules = reactive<FormRules>({
  name: [{ required: true, message: '请输入培训名称', trigger: 'blur' }],
  description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
  jobLevel: [{ required: true, message: '请选择岗位级别', trigger: 'change' }],
  job: [{ required: true, message: '请选择岗位', trigger: 'change' }],
  jobType: [{ required: true, message: '请选择岗位类型', trigger: 'change' }],
  thumbnail: [{ required: true, message: '请上传培训封面', trigger: 'change' }],
  videoList: [{ required: true, type: 'array', min: 1, message: '请至少上传一个视频', trigger: 'change' }],
  addressDetail: [{ required: true, message: '请输入地址', trigger: 'blur' }],
  timeRange: [{ required: true, type: 'array', min: 2, message: '请选择培训时间', trigger: 'change' }],
  applyRange: [{ required: true, type: 'array', min: 2, message: '请选择报名时间', trigger: 'change' }]
});

const formatFileSize = (size: number) => {
  if (size >= 1024 * 1024 * 1024) {
    return `${(size / 1024 / 1024 / 1024).toFixed(2)}GB`;
  }
  if (size >= 1024 * 1024) {
    return `${(size / 1024 / 1024).toFixed(1)}MB`;
  }
  if (size >= 1024) {
    return `${(size / 1024).toFixed(1)}KB`;
  }
  return `${size}B`;
};

const formatDuration = (totalSeconds: number) => {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  return [hours, minutes, seconds].map((item) => item.toString().padStart(2, '0')).join(':');
};

const parseDuration = (duration?: string) => {
  if (!duration) return 0;
  const parts = duration.split(':').map((item) => Number(item));
  if (parts.length === 3) {
    return parts[0] * 3600 + parts[1] * 60 + parts[2];
  }
  if (parts.length === 2) {
    return parts[0] * 60 + parts[1];
  }
  return parts[0] || 0;
};

const calcTotalDuration = (videoList: any[]) => {
  const totalSeconds = videoList.reduce((sum, item) => sum + parseDuration(item.duration), 0);
  return totalSeconds > 0 ? formatDuration(totalSeconds) : '';
};

const getVideoDuration = (file: File) => new Promise<string>((resolve) => {
  const video = document.createElement('video');
  const objectUrl = URL.createObjectURL(file);
  video.preload = 'metadata';
  video.onloadedmetadata = () => {
    const duration = Number.isFinite(video.duration) ? Math.round(video.duration) : 0;
    URL.revokeObjectURL(objectUrl);
    resolve(formatDuration(duration));
  };
  video.onerror = () => {
    URL.revokeObjectURL(objectUrl);
    resolve('00:00:00');
  };
  video.src = objectUrl;
});

const loadSelectOptions = async () => {
  const [jobLevelRes, jobTypeRes, positionRes] = await Promise.all([
    getDicts('main_position_level'),
    getDicts('main_position_type'),
    listPosition({ pageNum: 1, pageSize: 999 })
  ]);
  jobLevelOptions.value = (jobLevelRes.data || []).map((item: any) => ({
    label: item.dictLabel,
    value: item.dictLabel
  }));
  jobTypeOptions.value = (jobTypeRes.data || []).map((item: any) => ({
    label: item.dictLabel,
    value: item.dictLabel
  }));
  jobOptions.value = (positionRes.rows || []).map((item: any) => ({
    label: item.postName,
    value: item.postName
  }));
};

onMounted(async () => {
  await loadSelectOptions();
  if (props.initialData) {
    // 编辑模式: 回显数据
    form.id = props.initialData.id;
    form.name = props.initialData.name || '';
    form.thumbnail = props.initialData.thumbnail;
    form.thumbnailUrl = props.initialData.thumbnailUrl || '';
    form.description = props.initialData.description || '';
    form.jobLevel = props.initialData.jobLevel || '';
    form.job = props.initialData.job || '';
    form.jobType = props.initialData.jobType || '';
    form.sortOrder = props.initialData.sortOrder?.toString() || '';
    form.status = props.initialData.status ?? 1;
    form.organizer = props.initialData.organizer || '';
    form.tags = props.initialData.tags || '';

    // 视频列表
    if (props.initialData.videoList && props.initialData.videoList.length > 0) {
      form.videoList = props.initialData.videoList.map((v: any) => ({
        id: v.id,
        name: v.name,
        fileSize: v.fileSize,
        fileType: v.fileType,
        duration: v.duration,
        ossId: v.ossId,
        fileUrl: v.fileUrl,
        sortOrder: v.sortOrder
      }));
    }

    // 线下培训地址
    form.city = props.initialData.city || '上海市';
    form.area = props.initialData.area || '黄浦区';
    form.region = ['上海市', form.city || '上海市', form.area || '黄浦区'];
    form.addressDetail = props.initialData.addressDetail || '';

    // 时间范围
    if (props.initialData.trainingStartTime && props.initialData.trainingEndTime) {
      form.timeRange = [props.initialData.trainingStartTime, props.initialData.trainingEndTime];
    }
    if (props.initialData.applyStartTime && props.initialData.applyEndTime) {
      form.applyRange = [props.initialData.applyStartTime, props.initialData.applyEndTime];
    }
  }
});

const handleUploadThumbnail = () => {
  thumbnailInputRef.value?.click();
};

const handleThumbnailFileChange = async (event: Event) => {
  const target = event.target as HTMLInputElement;
  const rawFile = target.files?.[0];
  if (!rawFile) {
    return;
  }
  if (!['image/jpeg', 'image/png'].includes(rawFile.type)) {
    ElMessage.error('请上传 JPG、PNG 格式图片');
    target.value = '';
    return;
  }
  if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error('图片不能超过10M');
    target.value = '';
    return;
  }
  thumbnailUploading.value = true;
  try {
    const res = await uploadTrainingFile(rawFile);
    form.thumbnail = res.data?.ossId;
    form.thumbnailUrl = res.data?.url || URL.createObjectURL(rawFile);
    formRef.value?.clearValidate('thumbnail');
    ElMessage.success('封面上传成功');
  } catch (error) {
    ElMessage.error('封面上传失败');
  } finally {
    target.value = '';
    thumbnailUploading.value = false;
  }
};

const handleUploadVideo = () => {
  videoInputRef.value?.click();
};

const handleVideoFileChange = async (event: Event) => {
  const target = event.target as HTMLInputElement;
  const rawFile = target.files?.[0];
  if (!rawFile) {
    return;
  }
  const extension = rawFile.name.split('.').pop()?.toLowerCase() || '';
  const allowTypes = ['mp4', 'avi', 'wmv', 'mov', 'flv', 'rmvb', '3gp', 'm4v', 'mkv'];
  if (!allowTypes.includes(extension)) {
    ElMessage.error('视频格式不支持');
    target.value = '';
    return;
  }
  if (rawFile.size / 1024 / 1024 / 1024 > 10) {
    ElMessage.error('视频不能超过10G');
    target.value = '';
    return;
  }
  videoUploading.value = true;
  try {
    const duration = await getVideoDuration(rawFile);
    const res = await uploadTrainingFile(rawFile);
    form.videoList.push({
      name: res.data?.originalName || res.data?.fileName || rawFile.name,
      fileSize: formatFileSize(rawFile.size),
      fileType: extension.toUpperCase(),
      duration,
      ossId: res.data?.ossId,
      fileUrl: res.data?.url,
      sortOrder: form.videoList.length + 1
    });
    formRef.value?.clearValidate('videoList');
    ElMessage.success('视频上传成功');
  } catch (error) {
    ElMessage.error('视频上传失败');
  } finally {
    target.value = '';
    videoUploading.value = false;
  }
};

const removeVideo = (index: number) => {
  form.videoList.splice(index, 1);
};

const handleCloseTag = (tag: string) => {
  const list = tagList.value.filter(t => t !== tag);
  tagList.value = list;
};

const showInputTag = () => {
  inputTagVisible.value = true;
  nextTick(() => {
    inputTagRef.value?.focus();
  });
};

const handleInputTagConfirm = () => {
  if (inputTagValue.value) {
    const list = [...tagList.value, inputTagValue.value];
    tagList.value = list;
  }
  inputTagVisible.value = false;
  inputTagValue.value = '';
};

const handleSubmit = async () => {
  if (!formRef.value) return;
  await formRef.value.validate((valid) => {
    if (valid) {
      if (props.type === 'offline') {
        const [province, cityLevel, district] = form.region || [];
        // 合并省+市到 city（直辖市跳过"市辖区"）
        const mergedCity = cityLevel && !cityLevel.includes('市辖区')
          ? `${province}${cityLevel}`
          : province;
        form.city = mergedCity || '上海市';
        form.area = district || '';
      }
      // 构造提交数据
      const submitData: any = {
        id: form.id,
        name: form.name,
        description: form.description,
        thumbnail: form.thumbnail,
        jobLevel: form.jobLevel,
        job: form.job,
        jobType: form.jobType,
        status: form.status
      };

      if (props.type === 'video') {
        submitData.sortOrder = form.sortOrder ? parseInt(form.sortOrder) : 0;
        submitData.duration = calcTotalDuration(form.videoList);
        submitData.videoList = form.videoList.map((v, i) => ({
          id: v.id,
          name: v.name,
          ossId: v.ossId,
          fileUrl: v.fileUrl,
          fileSize: v.fileSize,
          fileType: v.fileType,
          duration: v.duration,
          sortOrder: i + 1
        }));
      }

      if (props.type === 'offline') {
        submitData.city = form.city;
        submitData.area = form.area;
        submitData.addressDetail = form.addressDetail;
        submitData.organizer = form.organizer;
        submitData.tags = form.tags;
        if (form.timeRange && form.timeRange.length === 2) {
          submitData.trainingStartTime = form.timeRange[0];
          submitData.trainingEndTime = form.timeRange[1];
        }
        if (form.applyRange && form.applyRange.length === 2) {
          submitData.applyStartTime = form.applyRange[0];
          submitData.applyEndTime = form.applyRange[1];
        }
      }

      emit('submit', submitData);
    }
  });
};
</script>

<style scoped lang="scss">
.train-form {
  background-color: #f0f2f5;
  min-height: calc(100vh - 84px);
  padding: 20px 40px;

  @media (max-width: 768px) {
    padding: 10px;
  }

  .form-breadcrumb {
    margin-bottom: 20px;
  }

  .form-header {
    margin-bottom: 30px;
  }

  .form-wrapper {
    max-width: 1000px;
    margin: 0 auto;
    background-color: #fff;
    padding: 40px 60px;
    border: 2px solid #409eff;
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);

    @media (max-width: 768px) {
      padding: 20px;
    }
  }

  .submit-btn {
    padding: 0 30px;
    height: 36px;
    background-color: #409eff;
    border-color: #409eff;
  }

  .back-btn {
    padding: 0 30px;
    height: 36px;
    color: #606266;
  }

  .thumbnail-uploader {
    .avatar-uploader {
      width: 160px;
      height: 80px;
      border: 1px dashed #d9d9d9;
      border-radius: 4px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      display: flex;
      align-items: center;
      justify-content: center;

      &:hover {
        border-color: #409eff;
      }
    }

    .avatar-preview {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .avatar-uploader-icon {
      font-size: 20px;
      color: #8c939d;
    }
  }

  .video-table {
    :deep(.el-table__header) {
      background-color: #f7f8fa;
    }
  }

  .address-container {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    width: 100%;
    max-width: 720px;

    .region-cascader {
      width: 240px;
      flex-shrink: 0;
    }

    .address-detail-input {
      width: 400px;
      flex: 1;
    }
  }

  :deep(.el-form-item__label) {
    color: #4e5969;
    font-weight: 500;
  }
}
</style>
