<template>
  <el-form label-width="120px" size="default" class="cse-form" :model="local">
    <el-row :gutter="16">
      <el-col :span="8">
        <el-form-item label="长度 (m)">
          <el-input-number :model-value="local.bodyLengthM" :min="0.12" :max="4" :step="0.01" :precision="2" @update:model-value="(v) => update({ bodyLengthM: Number(v ?? 0) })" />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="宽度 (m)">
          <el-input-number :model-value="local.bodyWidthM" :min="0.08" :max="3" :step="0.01" :precision="2" @update:model-value="(v) => update({ bodyWidthM: Number(v ?? 0) })" />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="显示名称">
          <el-switch :model-value="local.showLabel" @update:model-value="(v: string | number | boolean) => update({ showLabel: Boolean(v) })" />
        </el-form-item>
      </el-col>
    </el-row>

    <el-row :gutter="16">
      <el-col :span="8">
        <el-form-item label="车体颜色">
          <el-color-picker
            :model-value="argbToHex(local.bodyColorArgb)"
            show-alpha
            @update:model-value="(v: string | null) => update({ bodyColorArgb: v ? hexToArgb(v) : 0 })"
          />
          <code class="cse-color-code">#{{ argbToHex(local.bodyColorArgb).toUpperCase() }}</code>
          <span class="cse-color-hint">无报警/上线时生效</span>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="描边颜色">
          <el-color-picker
            :model-value="argbToHex(local.outlineColorArgb)"
            show-alpha
            @update:model-value="(v: string | null) => update({ outlineColorArgb: v ? hexToArgb(v) : 0 })"
          />
          <code class="cse-color-code">#{{ argbToHex(local.outlineColorArgb).toUpperCase() }}</code>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="标签颜色">
          <el-color-picker
            :model-value="argbToHex(local.labelColorArgb)"
            show-alpha
            @update:model-value="(v: string | null) => update({ labelColorArgb: v ? hexToArgb(v) : 0 })"
          />
          <code class="cse-color-code">#{{ argbToHex(local.labelColorArgb).toUpperCase() }}</code>
        </el-form-item>
      </el-col>
    </el-row>

    <el-form-item label="3D 模型路径">
      <div class="cse-model-row">
        <el-input
          :model-value="local.modelPath"
          placeholder="如 ./models/agv-base.glb（路径仅保存，3D 替换矩形渲染由后续阶段接入）"
          clearable
          @update:model-value="(v: string) => update({ modelPath: v ?? '' })"
        >
          <template #append>
            <el-button @click="pickModelFile">浏览…</el-button>
          </template>
        </el-input>
        <input
          ref="fileInput"
          type="file"
          accept=".glb,.gltf,.obj,.fbx"
          style="display:none"
          @change="onFileSelected"
        />
      </div>
      <p class="cse-model-hint">
        现版本仅记录文件路径作为元信息。3D 渲染替代矩形将在后续阶段实现（CycleGUI Workspace LoadModel）。
        如需上传文件到服务器请先用其它方式将模型放到 SimpleLite 可访问的相对路径。
      </p>
    </el-form-item>

    <el-form-item>
      <el-button type="primary" :loading="saving" @click="$emit('save')">保存此车型</el-button>
      <el-button v-if="hasOverride" type="warning" plain @click="$emit('reset')">恢复为默认</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { CarStyleDto } from '@/api/reflection'

const props = defineProps<{
  typeFullName: string
  modelValue: CarStyleDto
  hasOverride: boolean
  saving: boolean
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', v: CarStyleDto): void
  (e: 'save'): void
  (e: 'reset'): void
}>()

const local = computed<CarStyleDto>(() => props.modelValue)

function update(patch: Partial<CarStyleDto>) {
  emit('update:modelValue', { ...local.value, ...patch })
}

const fileInput = ref<HTMLInputElement | null>(null)
function pickModelFile() {
  fileInput.value?.click()
}
function onFileSelected(ev: Event) {
  const target = ev.target as HTMLInputElement
  const file = target.files?.[0]
  if (!file) return
  // 浏览器禁止读取真实绝对路径，这里只保留文件名作为提示，由用户改写为相对项目可访问的路径。
  update({ modelPath: file.name })
  target.value = ''
}

function argbToHex(argb: number): string {
  const a = (argb >>> 24) & 0xff
  const r = (argb >>> 16) & 0xff
  const g = (argb >>> 8) & 0xff
  const b = argb & 0xff
  const hex = (n: number) => n.toString(16).padStart(2, '0')
  return `${hex(r)}${hex(g)}${hex(b)}${hex(a)}`
}
function hexToArgb(hex: string): number {
  const m = hex.replace(/^#/, '')
  if (m.length === 6) {
    const r = parseInt(m.slice(0, 2), 16)
    const g = parseInt(m.slice(2, 4), 16)
    const b = parseInt(m.slice(4, 6), 16)
    return ((0xff << 24) | (r << 16) | (g << 8) | b) >>> 0
  }
  if (m.length === 8) {
    const r = parseInt(m.slice(0, 2), 16)
    const g = parseInt(m.slice(2, 4), 16)
    const b = parseInt(m.slice(4, 6), 16)
    const a = parseInt(m.slice(6, 8), 16)
    return ((a << 24) | (r << 16) | (g << 8) | b) >>> 0
  }
  return 0
}
</script>

<style scoped>
.cse-form {
  padding: 8px 4px;
}
.cse-color-code {
  font-family: 'JetBrains Mono', Consolas, monospace;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-left: 8px;
}
.cse-color-hint {
  font-size: 12px;
  color: var(--el-text-color-secondary);
  margin-left: 8px;
}
.cse-model-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}
.cse-model-hint {
  margin: 6px 0 0 0;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  line-height: 1.55;
}
</style>
