<script setup lang="ts">
import { computed, ref } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import type {
  GenerationControlOptions,
  ProcessType,
  StructuredProcessOptions,
  UnstructuredProcessOptions,
} from './types'
import StructuredOptionsPanel from './StructuredOptionsPanel.vue'
import UnstructuredOptionsPanel from './UnstructuredOptionsPanel.vue'

const props = defineProps<{
  name: string
  description: string
  processType: ProcessType
  structuredOptions: StructuredProcessOptions
  unstructuredOptions: UnstructuredProcessOptions
}>()

const emit = defineEmits<{
  'update:name': [value: string]
  'update:description': [value: string]
  'update:processType': [value: ProcessType]
  'update:structuredOptions': [value: StructuredProcessOptions]
  'update:unstructuredOptions': [value: UnstructuredProcessOptions]
}>()

const formRef = ref<FormInstance>()
const unstructuredOptionsPanelRef = ref<InstanceType<typeof UnstructuredOptionsPanel>>()
const validationAttempted = ref(false)
const formModel = computed(() => ({
  name: props.name,
  processType: props.processType,
}))

const splitTotal = computed(() => {
  const { train, validation, test } = props.structuredOptions.datasetSplit
  return train + validation + test
})

const unstructuredSplitTotal = computed(() => {
  const { train, validation, test } = props.unstructuredOptions.datasetSplit
  return train + validation + test
})

const activeGenerationOptions = computed<GenerationControlOptions | null>(() => {
  if (props.processType === 'structured') return props.structuredOptions
  if (props.processType === 'unstructured') return props.unstructuredOptions
  return null
})

const qualityValidationMessage = computed(() => {
  const options = activeGenerationOptions.value
  if (!options) return ''
  if (options.qualityFilterEnabled && !options.filterLowQuality && !options.filterShortContent) {
    return '开启质量筛选后，请至少选择一项筛选规则'
  }
  if (options.qualityFilterEnabled && options.filterShortContent && options.minOutputLength < 1) {
    return '最少字数必须大于 0'
  }
  return ''
})

const chunkValidationMessage = computed(() => {
  if (props.unstructuredOptions.chunkOverlap >= props.unstructuredOptions.chunkSize) {
    return '重叠长度必须小于切片长度'
  }
  if (props.unstructuredOptions.minChunkSize > props.unstructuredOptions.chunkSize) {
    return '最小切片长度不能大于切片长度'
  }
  if (
    props.unstructuredOptions.chunkOverlap + props.unstructuredOptions.minChunkSize
    > props.unstructuredOptions.chunkSize
  ) {
    return '重叠长度与最小切片长度之和不能大于切片长度'
  }
  if (props.unstructuredOptions.chunkMethod === 'custom' && !props.unstructuredOptions.customDelimiter.trim()) {
    return '请输入自定义分隔符'
  }
  return ''
})

const rules: FormRules = {
  name: [
    { required: true, message: '请输入任务名称', trigger: 'blur' },
    { max: 50, message: '任务名称不能超过 50 个字符', trigger: 'blur' },
  ],
  processType: [{ required: true, message: '请选择数据处理类型', trigger: 'change' }],
}

async function validate() {
  validationAttempted.value = true
  if (!formRef.value) return false
  try {
    await formRef.value.validate()
    if (props.processType === 'structured' && splitTotal.value !== 100) {
      ElMessage.error('结构化数据处理：数据集划分比例总和必须为 100%')
      return false
    }
    if (props.processType === 'unstructured') {
      if (unstructuredSplitTotal.value !== 100) {
        ElMessage.error('非结构化数据处理：数据集划分比例总和必须为 100%')
        return false
      }
      if (chunkValidationMessage.value) {
        unstructuredOptionsPanelRef.value?.revealValidation()
        ElMessage.error(chunkValidationMessage.value)
        return false
      }
    }
    if (qualityValidationMessage.value) {
      ElMessage.error(qualityValidationMessage.value)
      return false
    }
    return true
  } catch {
    ElMessage.error('请完善标红的必填项')
    return false
  }
}

defineExpose({ validate })
</script>

<template>
  <section class="task-setup-step">
    <el-form ref="formRef" :model="formModel" :rules="rules" label-position="top" scroll-to-error>
      <div class="form-section">
        <h3>基本信息</h3>
        <div class="basic-grid">
          <el-form-item label="任务名称" prop="name" required>
            <el-input
              :model-value="name"
              maxlength="50"
              show-word-limit
              placeholder="例如：金融问答清洗任务"
              @update:model-value="emit('update:name', $event)"
            />
          </el-form-item>
          <el-form-item label="任务描述（选填）">
            <el-input
              :model-value="description"
              type="textarea"
              :rows="3"
              maxlength="200"
              show-word-limit
              placeholder="简要说明本次数据处理目标"
              @update:model-value="emit('update:description', $event)"
            />
          </el-form-item>
        </div>
      </div>

      <div class="form-section">
        <div class="section-title-row">
          <div>
            <h3>处理类型</h3>
            <p>类型会影响下一步支持的数据源格式和后续预览方式</p>
          </div>
        </div>
        <el-form-item prop="processType" class="type-form-item">
          <div class="type-options">
            <button
              type="button"
              class="type-option"
              :class="{ 'is-active': processType === 'structured' }"
              @click="emit('update:processType', 'structured')"
            >
              <span class="type-icon"><i class="fa fa-table" /></span>
              <span>
                <strong>结构化数据</strong>
                <small>适用于 CSV、Excel、JSONL 等固定字段数据</small>
              </span>
              <i class="fa fa-check-circle selection-mark" />
            </button>
            <button
              type="button"
              class="type-option"
              :class="{ 'is-active': processType === 'unstructured' }"
              @click="emit('update:processType', 'unstructured')"
            >
              <span class="type-icon"><i class="fa fa-file-text-o" /></span>
              <span>
                <strong>非结构化数据</strong>
                <small>适用于文档、文本、问答等需要切分的数据</small>
              </span>
              <i class="fa fa-check-circle selection-mark" />
            </button>
            <button
              type="button"
              class="type-option"
              :class="{ 'is-active': processType === 'external' }"
              @click="emit('update:processType', 'external')"
            >
              <span class="type-icon"><i class="fa fa-cloud-download" /></span>
              <span>
                <strong>外来数据源拉取</strong>
                <small>适用于数据库、API 接口等需远程拉取的外部数据</small>
              </span>
              <i class="fa fa-check-circle selection-mark" />
            </button>
          </div>
        </el-form-item>
      </div>

      <StructuredOptionsPanel
        v-if="processType === 'structured'"
        :options="structuredOptions"
        :validation-attempted="validationAttempted"
        :quality-validation-message="qualityValidationMessage"
        @update:options="emit('update:structuredOptions', $event)"
      />

      <UnstructuredOptionsPanel
        v-if="processType === 'unstructured'"
        ref="unstructuredOptionsPanelRef"
        :options="unstructuredOptions"
        :validation-attempted="validationAttempted"
        :quality-validation-message="qualityValidationMessage"
        :chunk-validation-message="chunkValidationMessage"
        @update:options="emit('update:unstructuredOptions', $event)"
      />
    </el-form>
  </section>
</template>

<style scoped lang="scss">
.task-setup-step {
  width: 100%;
}

.form-section {
  padding: 0 0 26px;
  margin-bottom: 26px;
  border-bottom: 1px solid #edf0f5;

  h3 {
    margin: 0 0 16px;
    color: #2f3747;
    font-size: 15px;
    font-weight: 650;
  }
}

.basic-grid {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.section-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;

  h3 {
    margin-bottom: 5px;
  }

  p {
    margin: 0;
    color: #8a93a3;
    font-size: 12px;
  }
}

.type-form-item {
  margin-top: 16px;
}

.type-options {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  width: 100%;
}

.type-option {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 96px;
  padding: 18px;
  color: #4b5563;
  text-align: left;
  background: #fff;
  border: 1px solid #dfe3ea;
  border-radius: 9px;
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease;

  &:hover {
    border-color: #a8a3ff;
  }

  &.is-active {
    background: #fafaff;
    border-color: #5b50f2;
    box-shadow: 0 0 0 1px rgba(91, 80, 242, 0.08);
  }

  strong,
  small {
    display: block;
  }

  strong {
    margin-bottom: 6px;
    color: #262d3d;
    font-size: 14px;
  }

  small {
    color: #7b8495;
    font-size: 12px;
    line-height: 1.6;
  }
}

.type-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  color: #5b50f2;
  font-size: 18px;
  background: #f0efff;
  border-radius: 9px;
}

.selection-mark {
  position: absolute;
  top: 12px;
  right: 12px;
  color: #5b50f2;
  opacity: 0;
}

.type-option.is-active .selection-mark {
  opacity: 1;
}

@media (max-width: 900px) {
  .type-options {
    grid-template-columns: minmax(0, 1fr);
  }
}
</style>
