<template>
  <el-dialog
    :model-value="modelValue"
    title="AI 生图"
    width="640px"
    class="ai-generate-dialog"
    @update:model-value="(v: boolean) => emit('update:modelValue', v)"
    @close="onClose"
  >
    <el-alert v-if="!configured" type="warning" :closable="false" class="cfg-alert">
      尚未配置 AI 服务（apiKey / endpoint）。请先到
      <el-link type="primary" @click="goConfig">系统级配置 → AI 服务</el-link>
      完成配置。
    </el-alert>

    <el-form label-width="100px" size="default">
      <el-form-item label="提示词" required>
        <el-input
          v-model="form.prompt"
          type="textarea"
          :rows="4"
          placeholder="一条 U 型生产线，含 5 个工站，间距 2m，方向单向通行..."
        />
      </el-form-item>
      <el-form-item label="参考图片">
        <el-upload
          drag
          :auto-upload="false"
          :show-file-list="false"
          accept="image/*"
          @change="onPickImage"
        >
          <div class="upload-hint">
            <el-icon><UploadFilled /></el-icon>
            <span>{{ form.referenceImageBase64 ? '已选择图片 (点击替换)' : '拖入或点击上传参考图（可选，多模态）' }}</span>
          </div>
        </el-upload>
      </el-form-item>
      <el-form-item label="生成模式">
        <el-radio-group v-model="form.mode">
          <el-radio-button value="sites">仅站点</el-radio-button>
          <el-radio-button value="tracks">仅路径</el-radio-button>
          <el-radio-button value="sites+tracks">站点+路径</el-radio-button>
          <el-radio-button value="full">完整地图</el-radio-button>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="范围 (mm)">
        <el-input-number v-model="bounds[0]" placeholder="x1" :step="500" />
        <el-input-number v-model="bounds[1]" placeholder="y1" :step="500" class="ml" />
        <el-input-number v-model="bounds[2]" placeholder="x2" :step="500" class="ml" />
        <el-input-number v-model="bounds[3]" placeholder="y2" :step="500" class="ml" />
      </el-form-item>
      <el-form-item label="图层">
        <el-input v-model="form.layer" placeholder="ai-generated（默认）" />
      </el-form-item>
      <el-form-item label="附加约束">
        <el-input v-model="form.constraints" placeholder="例如：单向通行、最小转弯半径 1500mm" />
      </el-form-item>
    </el-form>

    <el-collapse v-if="result" v-model="resultPanel" class="result-panel">
      <el-collapse-item title="AI 返回 / 落地结果" name="r">
        <div v-if="result.assistantText" class="ai-text">{{ result.assistantText }}</div>
        <div class="ai-stat">
          落地对象 <b>{{ result.created?.length ?? 0 }}</b>，工具调用次数 <b>{{ result.usedTools }}</b>。
        </div>
        <el-table :data="result.created ?? []" size="small" max-height="220">
          <el-table-column label="工具" prop="tool" width="160" />
          <el-table-column label="kind" prop="kind" width="80" />
          <el-table-column label="id" prop="id" width="80" />
          <el-table-column label="typeName" prop="typeName" />
          <el-table-column label="错误">
            <template #default="{ row }">
              <el-tag v-if="row.error" type="danger" size="small">{{ row.error }}</el-tag>
            </template>
          </el-table-column>
        </el-table>
      </el-collapse-item>
    </el-collapse>

    <template #footer>
      <el-button @click="onClose">关闭</el-button>
      <el-button type="primary" :loading="busy" :disabled="!form.prompt.trim() || !configured" @click="onGenerate">
        生成并落地
      </el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import { ElMessage, type UploadFile } from 'element-plus'
import { mapEditApi, type AiMapGenerateRequest, type AiMapGenerateResult } from '@/api/mapEdit'
import { useRouter } from 'vue-router'

const props = defineProps<{
  modelValue: boolean
  configured: boolean
  /** 默认 bounds：x1, y1, x2, y2，mm。 */
  defaultBounds?: [number, number, number, number]
  /** 默认图层。 */
  defaultLayer?: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', v: boolean): void
  (e: 'generated', r: AiMapGenerateResult): void
}>()

const router = useRouter()
const busy = ref(false)
const result = ref<AiMapGenerateResult | null>(null)
const resultPanel = ref<string[]>(['r'])

const form = reactive<AiMapGenerateRequest>({
  prompt: '',
  mode: 'sites+tracks',
  referenceImageBase64: undefined,
  layer: props.defaultLayer ?? 'ai-generated',
  constraints: ''
})

const bounds = ref<[number, number, number, number]>(
  props.defaultBounds ?? [-10000, -10000, 10000, 10000]
)

watch(() => props.defaultBounds, (nv) => { if (nv) bounds.value = nv as [number, number, number, number] })
watch(() => props.defaultLayer, (nv) => { if (nv) form.layer = nv })

function onClose() {
  emit('update:modelValue', false)
}

function goConfig() {
  emit('update:modelValue', false)
  router.push('/admin/config/system')
}

async function onPickImage(f: UploadFile) {
  if (!f.raw) return
  const reader = new FileReader()
  reader.onload = () => {
    const result = String(reader.result || '')
    const base64 = result.includes(',') ? result.split(',', 2)[1]! : result
    form.referenceImageBase64 = base64
  }
  reader.readAsDataURL(f.raw)
}

async function onGenerate() {
  try {
    busy.value = true
    form.bounds = bounds.value
    const r = await mapEditApi.aiMapGenerate(form)
    result.value = r
    ElMessage.success(`AI 已生成 ${r.created?.length ?? 0} 个对象`)
    emit('generated', r)
  } catch (err) {
    ElMessage.error(`AI 生图失败：${(err as Error).message}`)
  } finally {
    busy.value = false
  }
}
</script>

<style scoped>
.cfg-alert { margin-bottom: 12px; }
.ml { margin-left: 6px; }
/* dialog 内文字色统一用 inherit / CSS 变量，避免白底主题下出现 "白字白底" 看不清。 */
.upload-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  color: var(--el-text-color-regular, rgba(232,215,245,0.7));
}
.result-panel { margin-top: 8px; }
.ai-text {
  color: var(--el-text-color-primary, rgba(232,215,245,0.85));
  padding: 6px 0;
  white-space: pre-wrap;
}
.ai-stat {
  padding: 6px 0;
  color: var(--el-text-color-primary, rgba(232,215,245,0.85));
}
.ai-stat b { color: var(--mg-accent, #c4a4ff); }
</style>

<!--
  非 scoped：el-dialog 会 teleport 到 body，scoped 的 data-v 不一定能命中对话框盒子。
  深色主题下全局 --el-bg-color 仅 0.55 不透明度，导致 AI 生图对话框「太透明、看不清」。
  这里按主题色把对话框背景设为实底（rgb 三元组无 alpha = 完全不透明），
  同时兼容 class 落在 .el-dialog 盒子或外层 overlay 两种情况。
  fame-lavender 浅色主题已有 `.el-dialog{background:#fff!important}` 且特异性更高，不受影响。
-->
<style>
.ai-generate-dialog.el-dialog,
.ai-generate-dialog .el-dialog {
  background-color: rgb(var(--mg-bg-card-rgb)) !important;
  box-shadow: 0 24px 60px rgba(8, 2, 16, 0.6) !important;
}
</style>
