<script setup>
import { ArrowLeft } from '@element-plus/icons-vue'
import { ElAutoResizer, ElMessage, ElTableV2 } from 'element-plus'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { createPackage, getAllDataFiles, getPkgCategoryTree, previewPackage } from '@/api/packageManagement'
import { getCategoryTree, getQualityConfig } from '@/api/dataManagement'
import DataCurve from '@/views/DataManagement/components/DataCurve.vue'

const emit = defineEmits(['cancel', 'saved'])

// ── data files ────────────────────────────────────────────────────────────────
const allFiles = ref([])
const selectedFileIds = ref([])
const fileTableRef = ref(null)
const fileSearchText = ref('')
const fileFilterCategoryId = ref('')

const filteredFiles = computed(() => {
  let list = allFiles.value
  if (fileFilterCategoryId.value) {
    list = list.filter((f) => String(f.category_id) === fileFilterCategoryId.value)
  }
  const kw = fileSearchText.value.trim().toLowerCase()
  if (!kw) return list
  return list.filter(
    (f) =>
      f.filename.toLowerCase().includes(kw) ||
      (f.remark || '').toLowerCase().includes(kw),
  )
})

const handleFileSelectionChange = (rows) => {
  selectedFileIds.value = rows.map((r) => r.id)
}

// ── categories ────────────────────────────────────────────────────────────────
const categoryOptions = ref([])
const dataCategoryOptions = ref([])

const loadCategories = async () => {
  const data = await getPkgCategoryTree()
  const source = Array.isArray(data) ? data : []
  categoryOptions.value = source
    .filter((item) => String(item?.id) !== 'all')
    .map((item) => ({ label: item.name, value: String(item.id) }))
}

const loadDataCategories = async () => {
  const data = await getCategoryTree()
  const source = Array.isArray(data) ? data : []
  dataCategoryOptions.value = source
    .filter((item) => String(item?.id) !== 'all')
    .map((item) => ({ label: item.name, value: String(item.id) }))
}

// ── form ──────────────────────────────────────────────────────────────────────
const form = reactive({
  categoryId: '',
  name: '',
  remark: '',
})

// ── clean rules ───────────────────────────────────────────────────────────────
const cleanRules = reactive({
  enabled: false,  newton_interp: false,  current_min: null,
  current_max: null,
  voltage_min: null,
  voltage_max: null,
  temperature_min: null,
  temperature_max: null,
})

const applyQualityConfigToCleanRules = (configs) => {
  const map = {}
  for (const cfg of configs) {
    map[cfg.field_name] = cfg
  }
  if (map.current) {
    if (cleanRules.current_min === null) cleanRules.current_min = map.current.min_value ?? null
    if (cleanRules.current_max === null) cleanRules.current_max = map.current.max_value ?? null
  }
  if (map.voltage) {
    if (cleanRules.voltage_min === null) cleanRules.voltage_min = map.voltage.min_value ?? null
    if (cleanRules.voltage_max === null) cleanRules.voltage_max = map.voltage.max_value ?? null
  }
  // temperature: take broader range of set_temperature and actual_temperature
  const setTMin = map.set_temperature?.min_value ?? null
  const setTMax = map.set_temperature?.max_value ?? null
  const actTMin = map.actual_temperature?.min_value ?? null
  const actTMax = map.actual_temperature?.max_value ?? null
  if (cleanRules.temperature_min === null) {
    const candidates = [setTMin, actTMin].filter((v) => v !== null)
    cleanRules.temperature_min = candidates.length ? Math.min(...candidates) : null
  }
  if (cleanRules.temperature_max === null) {
    const candidates = [setTMax, actTMax].filter((v) => v !== null)
    cleanRules.temperature_max = candidates.length ? Math.max(...candidates) : null
  }
}

watch(
  () => cleanRules.enabled,
  async (enabled) => {
    if (!enabled) return
    // Only auto-fill if all fields are still null (user hasn't typed yet)
    const allNull =
      cleanRules.current_min === null &&
      cleanRules.current_max === null &&
      cleanRules.voltage_min === null &&
      cleanRules.voltage_max === null &&
      cleanRules.temperature_min === null &&
      cleanRules.temperature_max === null
    if (!allNull) return
    try {
      const configs = await getQualityConfig()
      applyQualityConfigToCleanRules(configs)
    } catch {
      // ignore: quality config may not be configured yet
    }
  },
)

const cleanRulesPayload = computed(() => {
  if (!cleanRules.enabled) return null
  return {
    enabled: true,
    newton_interp: cleanRules.newton_interp,
    current_min: cleanRules.current_min ?? null,
    current_max: cleanRules.current_max ?? null,
    voltage_min: cleanRules.voltage_min ?? null,
    voltage_max: cleanRules.voltage_max ?? null,
    temperature_min: cleanRules.temperature_min ?? null,
    temperature_max: cleanRules.temperature_max ?? null,
  }
})

// ── smooth ────────────────────────────────────────────────────────────────────
const smooth = reactive({
  enabled: false,
  window: 5,
})

const smoothPayload = computed(() => {
  if (!smooth.enabled) return null
  return { enabled: true, window: smooth.window ?? 5 }
})

// ── auto split ───────────────────────────────────────────────────────────────
const autoSplit = ref(false)
const rowRange = reactive({
  enabled: false,
  start: null,
  end: null,
})

const rowRangeError = computed(() => {
  if (!rowRange.enabled) return ''
  const s = rowRange.start
  const e = rowRange.end
  if (s !== null && s < 1) return '起始行不能小于 1'
  if (e !== null && e < 1) return '结束行不能小于 1'
  if (s !== null && e !== null && s > e) return '起始行不能大于结束行'
  return ''
})

const rowRangePayload = computed(() => {
  if (!rowRange.enabled) return { row_start: null, row_end: null }
  return {
    row_start: rowRange.start ?? null,
    row_end: rowRange.end ?? null,
  }
})

const previewLoading = ref(false)
const previewRecords = ref([])
const previewTotal = ref(0)
const previewMode = ref('table')

// 虚拟表格列定义
const previewColumns = [
  { key: 'time', dataKey: 'time', title: '时间', width: 160 },
  { key: 'current', dataKey: 'current', title: '电流', width: 100 },
  { key: 'voltage', dataKey: 'voltage', title: '电压', width: 100 },
  { key: 'set_temperature', dataKey: 'set_temperature', title: '设定温度', width: 110 },
  { key: 'actual_temperature', dataKey: 'actual_temperature', title: '实际温度', width: 110 },
]

// 曲线模式下最多采样 2000 个点，避免 canvas 过载
const curveRecords = computed(() => {
  const records = previewRecords.value
  if (records.length <= 2000) return records
  const step = Math.ceil(records.length / 2000)
  return records.filter((_, i) => i % step === 0)
})

let previewDebounceTimer = null

const triggerPreview = () => {
  clearTimeout(previewDebounceTimer)
  if (!selectedFileIds.value.length) {
    previewRecords.value = []
    previewTotal.value = 0
    return
  }
  previewDebounceTimer = setTimeout(async () => {
    previewLoading.value = true
    try {
      const result = await previewPackage(
        {
          file_ids: selectedFileIds.value,
          clean_rules: cleanRulesPayload.value,
          smooth: smoothPayload.value,
          ...rowRangePayload.value,
        },
      )
      previewRecords.value = result.records
      previewTotal.value = result.count
    } finally {
      previewLoading.value = false
    }
  }, 600)
}

watch(selectedFileIds, triggerPreview, { deep: true })
watch(cleanRules, triggerPreview, { deep: true })
watch(smooth, triggerPreview, { deep: true })
watch(rowRange, triggerPreview, { deep: true })

// ── save ──────────────────────────────────────────────────────────────────────
const saving = ref(false)

const handleGenerate = async () => {
  if (!form.name.trim()) {
    ElMessage.warning('请输入数据包名称')
    return
  }
  if (!selectedFileIds.value.length) {
    ElMessage.warning('请至少选择一个数据文件')
    return
  }
  if (rowRangeError.value) {
    ElMessage.warning(rowRangeError.value)
    return
  }

  saving.value = true
  try {
    await createPackage({
      name: form.name.trim(),
      category_id: form.categoryId || null,
      remark: form.remark.trim() || null,
      file_ids: selectedFileIds.value,
      clean_rules: cleanRulesPayload.value,
      smooth: smoothPayload.value,
      auto_split: autoSplit.value,
      ...rowRangePayload.value,
    })
    ElMessage.success(autoSplit.value ? '数据包已自动划分为训练集/验证集/测试集' : '数据包创建成功')
    emit('saved')
  } finally {
    saving.value = false
  }
}

// ── init ──────────────────────────────────────────────────────────────────────
onMounted(async () => {
  const [filesData] = await Promise.all([getAllDataFiles(), loadCategories(), loadDataCategories()])
  allFiles.value = filesData
})
</script>

<template>
  <div class="add-pkg-page">
    <!-- header -->
    <div class="add-pkg-header">
      <el-button :icon="ArrowLeft" plain @click="emit('cancel')">返回列表</el-button>
      <span class="add-pkg-title">新增数据包</span>
    </div>

    <!-- top: file selection -->
    <div class="section-card file-section">
      <div class="section-title">
        选择数据文件
        <span class="section-hint">已选 {{ selectedFileIds.length }} 个文件</span>
      </div>
      <div class="file-search-bar">
        <el-select
          v-model="fileFilterCategoryId"
          placeholder="全部分类"
          clearable
          style="width: 160px"
        >
          <el-option
            v-for="item in dataCategoryOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-input
          v-model="fileSearchText"
          placeholder="按文件名或备注搜索"
          clearable
          style="width: 240px"
        />
      </div>
      <el-table
        ref="fileTableRef"
        :data="filteredFiles"
        border
        stripe
        height="220"
        @selection-change="handleFileSelectionChange"
      >
        <el-table-column type="selection" width="46" />
        <el-table-column prop="filename" label="文件名" min-width="180" show-overflow-tooltip />
        <el-table-column prop="category_name" label="所属分类" width="110" show-overflow-tooltip />
        <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
        <el-table-column prop="data_count" label="数据量" width="80" align="center" />
        <el-table-column prop="uploaded_at" label="上传时间" width="150" />
      </el-table>
    </div>

    <!-- bottom: form + preview -->
    <div class="section-bottom">
      <!-- left: form -->
      <div class="section-card form-section">
        <div class="section-title">生成数据包</div>
        <el-form label-position="top" class="pkg-form">
          <el-form-item label="数据包分类">
            <el-select v-model="form.categoryId" placeholder="请选择（可选）" clearable style="width: 100%">
              <el-option
                v-for="item in categoryOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="数据包名称" required>
            <el-input v-model="form.name" maxlength="100" show-word-limit placeholder="请输入数据包名称" />
          </el-form-item>
          <el-form-item label="清洗规则">
            <div class="clean-rules-wrap">
              <el-checkbox v-model="cleanRules.enabled">剔除野值</el-checkbox>
              <div v-if="cleanRules.enabled" class="clean-range-grid">
                <div class="clean-range-row">
                  <span class="clean-range-label">电流范围 (A)</span>
                  <el-input-number
                    v-model="cleanRules.current_min"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最小值"
                    class="range-input"
                  />
                  <span class="range-sep">~</span>
                  <el-input-number
                    v-model="cleanRules.current_max"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最大值"
                    class="range-input"
                  />
                </div>
                <div class="clean-range-row">
                  <span class="clean-range-label">电压范围 (V)</span>
                  <el-input-number
                    v-model="cleanRules.voltage_min"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最小值"
                    class="range-input"
                  />
                  <span class="range-sep">~</span>
                  <el-input-number
                    v-model="cleanRules.voltage_max"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最大值"
                    class="range-input"
                  />
                </div>
                <div class="clean-range-row">
                  <span class="clean-range-label">温度范围 (℃)</span>
                  <el-input-number
                    v-model="cleanRules.temperature_min"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最小值"
                    class="range-input"
                  />
                  <span class="range-sep">~</span>
                  <el-input-number
                    v-model="cleanRules.temperature_max"
                    :controls="false"
                    :value-on-clear="null"
                    placeholder="最大值"
                    class="range-input"
                  />
                </div>
                <div class="clean-range-row newton-row">
                  <el-checkbox v-model="cleanRules.newton_interp">牛顿插值填补（剔除野值后自动插值）</el-checkbox>
                </div>
              </div>
            </div>
          </el-form-item>
          <el-form-item label="数据转换">
            <div class="smooth-wrap">
              <el-checkbox v-model="smooth.enabled">滑动均值法</el-checkbox>
              <div v-if="smooth.enabled" class="smooth-inputs">
                <span class="smooth-label">窗口长度</span>
                <el-input-number
                  v-model="smooth.window"
                  :min="2"
                  :max="500"
                  :precision="0"
                  :value-on-clear="5"
                  style="width: 90px"
                />
                <span class="smooth-unit">个点</span>
              </div>
            </div>
          </el-form-item>
          <el-form-item label="截取范围">
            <div class="row-range-wrap">
              <el-checkbox v-model="rowRange.enabled">启用行范围截取</el-checkbox>
              <div v-if="rowRange.enabled" class="row-range-inputs">
                <el-input-number
                  v-model="rowRange.start"
                  :controls="false"
                  :value-on-clear="null"
                  :min="1"
                  :precision="0"
                  placeholder="起始行"
                  class="range-input"
                />
                <span class="range-sep">~</span>
                <el-input-number
                  v-model="rowRange.end"
                  :controls="false"
                  :value-on-clear="null"
                  :min="1"
                  :precision="0"
                  placeholder="结束行"
                  class="range-input"
                />
                <span class="range-unit">行（含两端）</span>
                <div v-if="rowRangeError" class="row-range-error">{{ rowRangeError }}</div>
              </div>
            </div>
          </el-form-item>
          <el-form-item label="数据集划分">
            <div class="auto-split-wrap">
              <el-checkbox v-model="autoSplit">自动划分数据集（70/15/15）</el-checkbox>
              <div v-if="autoSplit" class="auto-split-hint">
                将生成三个数据包：《名称-训练集》《名称-验证集》《名称-测试集》
              </div>
            </div>
          </el-form-item>
          <el-form-item label="备注">
            <el-input
              v-model="form.remark"
              type="textarea"
              :rows="3"
              maxlength="500"
              show-word-limit
              placeholder="备注（可选）"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              :loading="saving"
              style="width: 100%"
              @click="handleGenerate"
            >
              {{ autoSplit ? '划分生成数据包 (70/15/15)' : '生成数据包' }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- right: preview -->
      <div class="section-card preview-section">
        <div class="section-title">
          生成结果预览
          <span v-if="previewTotal" class="section-hint">共 {{ previewTotal }} 条</span>
          <el-radio-group v-model="previewMode" size="small" style="margin-left: auto">
            <el-radio-button value="table">表格</el-radio-button>
            <el-radio-button value="curve">曲线</el-radio-button>
          </el-radio-group>
        </div>

        <div class="preview-content" v-loading="previewLoading">
          <el-empty
            v-if="!previewLoading && !previewRecords.length"
            description="请在上方选择数据文件，预览将自动更新"
            :image-size="80"
          />

          <el-auto-resizer v-else-if="previewMode === 'table'">
            <template #default="{ height, width }">
              <el-table-v2
                :columns="previewColumns"
                :data="previewRecords"
                :width="width"
                :height="height"
                :row-height="36"
                :header-height="40"
                fixed
              />
            </template>
          </el-auto-resizer>

          <DataCurve v-else :records="curveRecords" :total-count="previewTotal" />
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.add-pkg-page {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 0;
  overflow: hidden;
}

.add-pkg-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 20px;
  background: rgba(255, 255, 255, 0.9);
  border-bottom: 1px solid #e8edf3;
  flex-shrink: 0;
}

.add-pkg-title {
  font-size: 16px;
  font-weight: 600;
  color: #0f172a;
}

.section-card {
  background: #fff;
  border: 1px solid #e8edf3;
  border-radius: 8px;
  padding: 16px;
  overflow: hidden;
}

.section-title {
  font-size: 14px;
  font-weight: 600;
  color: #0f172a;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-hint {
  font-size: 12px;
  font-weight: 400;
  color: #64748b;
}

.file-search-bar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 10px;
}

.file-section {
  flex-shrink: 0;
  margin: 12px 12px 0;
}

.section-bottom {
  flex: 1;
  display: flex;
  gap: 12px;
  padding: 12px;
  overflow: hidden;
  min-height: 0;
}

.form-section {
  width: 320px;
  flex-shrink: 0;
  overflow-y: auto;
}

.preview-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;

  .section-title {
    flex-shrink: 0;
  }
}

.preview-content {
  flex: 1;
  overflow: hidden;
  min-height: 0;
}

.pkg-form {
  :deep(.el-form-item) {
    margin-bottom: 16px;
  }
}

.clean-rules-wrap {
  width: 100%;
}

.clean-range-grid {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.clean-range-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.clean-range-label {
  font-size: 12px;
  color: #475569;
  width: 86px;
  flex-shrink: 0;
}

.range-input {
  width: 88px;

  :deep(.el-input__inner) {
    text-align: center;
  }
}

.range-sep {
  font-size: 13px;
  color: #94a3b8;
}

.newton-row {
  margin-top: 4px;
}

.smooth-wrap {
  width: 100%;
}

.smooth-inputs {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

.smooth-label {
  font-size: 12px;
  color: #475569;
}

.smooth-unit {
  font-size: 12px;
  color: #94a3b8;
}

.auto-split-wrap {
  width: 100%;
}

.auto-split-hint {
  margin-top: 6px;
  font-size: 12px;
  color: #64748b;
  line-height: 1.6;
}

.row-range-wrap {
  width: 100%;
}

.row-range-inputs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.range-unit {
  font-size: 12px;
  color: #94a3b8;
}

.row-range-error {
  width: 100%;
  font-size: 12px;
  color: #f56c6c;
  margin-top: 2px;
}
</style>