<template>
  <div class="ota-workbench">
    <aside class="ota-nav" aria-label="OTA sections">
      <button
        v-for="item in nav"
        :key="item.key"
        type="button"
        class="ota-nav__item"
        :class="{ active: pane === item.key }"
        @click="pane = item.key"
      >
        <span class="ota-nav__label">{{ item.label }}</span>
        <span v-if="item.key === 'jobs' && activeJobCount" class="ota-nav__badge">{{ activeJobCount }}</span>
      </button>
    </aside>

    <section class="ota-main">
      <header class="ota-top">
        <div class="ota-top__target">
          <span class="ota-top__kicker">TARGET</span>
          <strong class="ota-top__name">{{ targetLabel }}</strong>
          <div v-if="target" class="ota-top__hashes">
            <span v-for="(h, k) in displaySummary" :key="k" class="hash-chip">
              <em>{{ k }}</em>{{ h }}
            </span>
          </div>
          <span v-else class="ota-top__hint">{{ hintUnset }}</span>
        </div>
        <el-button size="small" plain :icon="Refresh" :loading="loadingMeta" @click="refreshMeta">
          {{ labelRefresh }}
        </el-button>
      </header>

      <div class="ota-body">
        <OtaVehiclesPane
          v-if="pane === 'vehicles'"
          :can-write="canWrite"
          @job-created="onJobCreated"
          @pulled="onPulled"
        />
        <OtaPackagesPane v-else-if="pane === 'packages'" :can-write="canWrite" @changed="refreshMeta" />
        <OtaJobsPane v-else-if="pane === 'jobs'" :can-write="canWrite" />
        <OtaConfigPane v-else-if="pane === 'config'" :can-write="canWrite" @job-created="onJobCreated" />
        <OtaCustomFilePane v-else-if="pane === 'custom'" :can-write="canWrite" @job-created="onJobCreated" />
        <OtaSettingsPane v-else-if="pane === 'settings'" :can-write="canWrite" @saved="refreshMeta" />
      </div>
    </section>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { Refresh } from '@element-plus/icons-vue'
import { useOtaWorkbench } from '@/composables/useOtaWorkbench'
import type { OtaPane } from '@/types/ota'
import { OTA_COPY } from './otaCopy'
import OtaVehiclesPane from './OtaVehiclesPane.vue'
import OtaPackagesPane from './OtaPackagesPane.vue'
import OtaJobsPane from './OtaJobsPane.vue'
import OtaConfigPane from './OtaConfigPane.vue'
import OtaCustomFilePane from './OtaCustomFilePane.vue'
import OtaSettingsPane from './OtaSettingsPane.vue'

defineProps<{ canWrite: boolean }>()

const pane = ref<OtaPane>('vehicles')
const {
  target,
  targetSummary,
  targetLabel,
  activeJobCount,
  loadingMeta,
  refreshMeta,
  startPolling,
  stopPolling
} = useOtaWorkbench()

onMounted(startPolling)
onUnmounted(stopPolling)

const labelRefresh = OTA_COPY.refresh
const hintUnset = OTA_COPY.activateHint

const nav: { key: OtaPane; label: string }[] = [
  { key: 'vehicles', label: OTA_COPY.navVehicles },
  { key: 'packages', label: OTA_COPY.navPackages },
  { key: 'jobs', label: OTA_COPY.navJobs },
  { key: 'config', label: OTA_COPY.navConfig },
  { key: 'custom', label: OTA_COPY.navCustom },
  { key: 'settings', label: OTA_COPY.navSettings }
]

const displaySummary = computed(() => {
  const s = targetSummary.value
  const keys = ['M.exe', 'D.exe', 'C.exe']
  const out: Record<string, string> = {}
  for (const k of keys) {
    if (s[k]) out[k.replace('.exe', '')] = s[k]
  }
  return out
})

function onJobCreated() {
  pane.value = 'jobs'
  void refreshMeta()
}

function onPulled() {
  pane.value = 'packages'
  void refreshMeta()
}
</script>

<style scoped>
.ota-workbench {
  --ota-fg: rgb(var(--mg-text-tint-rgb));
  --ota-fg-soft: rgba(var(--mg-text-hi-rgb), 0.78);
  --ota-fg-muted: rgba(var(--mg-text-hi-rgb), 0.55);
  --ota-line: rgba(var(--mg-primary-rgb), 0.14);
  --ota-surface: rgba(var(--mg-bg-card-rgb), 0.96);
  --ota-rail: rgba(var(--mg-primary-rgb), 0.04);
  --ota-rail-active: rgba(var(--mg-primary-rgb), 0.12);
  --ota-chip: rgba(var(--mg-primary-rgb), 0.1);

  display: grid;
  grid-template-columns: 152px minmax(0, 1fr);
  min-height: min(72vh, 820px);
  border: 1px solid var(--ota-line);
  border-radius: 14px;
  overflow: hidden;
  background: var(--ota-surface);
  box-shadow: 0 10px 28px rgba(var(--mg-primary-rgb), 0.06);
  color: var(--ota-fg);
}

.ota-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 10px;
  background: var(--ota-rail);
  border-right: 1px solid var(--ota-line);
}

.ota-nav__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border: 0;
  background: transparent;
  color: var(--ota-fg-soft);
  text-align: left;
  padding: 10px 12px;
  border-radius: 10px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s ease, color 0.15s ease;
}

.ota-nav__item:hover {
  background: rgba(var(--mg-primary-rgb), 0.08);
  color: var(--mg-primary);
}

.ota-nav__item.active {
  background: var(--ota-rail-active);
  color: var(--mg-primary);
  box-shadow: inset 3px 0 0 var(--mg-primary);
  font-weight: 600;
}

.ota-nav__badge {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--mg-status-warning);
  color: #1f1408;
  font-size: 11px;
  font-family: var(--mg-font-mono);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.ota-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: transparent;
}

.ota-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--ota-line);
  background: linear-gradient(
    180deg,
    rgba(var(--mg-primary-rgb), 0.04) 0%,
    transparent 100%
  );
}

.ota-top__kicker {
  display: block;
  font-size: 10px;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--ota-fg-muted);
  margin-bottom: 4px;
}

.ota-top__name {
  font-size: 17px;
  font-weight: 650;
  color: var(--ota-fg);
  letter-spacing: -0.01em;
}

.ota-top__hint {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--mg-status-warning);
}

.ota-top__hashes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.hash-chip {
  font-family: var(--mg-font-mono);
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--ota-chip);
  color: var(--mg-primary);
  border: 1px solid rgba(var(--mg-primary-rgb), 0.16);
}

.hash-chip em {
  font-style: normal;
  margin-right: 6px;
  opacity: 0.65;
  font-weight: 600;
}

.ota-body {
  flex: 1;
  min-height: 0;
  padding: 14px 18px 18px;
  overflow: auto;
}
</style>

<!-- 非 scoped：保证表格勾选 / 卡片勾选在浅紫主题下可见（覆盖 theme 白底 !important） -->
<style>
.ota-workbench .el-checkbox__inner {
  width: 16px !important;
  height: 16px !important;
  background: #fff !important;
  border: 1.5px solid #7c3aed !important;
  box-sizing: border-box !important;
}
.ota-workbench .el-checkbox__inner::after {
  border-width: 0 0 2px 2px !important;
  height: 7px !important;
  left: 4px !important;
  top: 1px !important;
  width: 4px !important;
}
.ota-workbench .el-checkbox__input.is-checked .el-checkbox__inner,
.ota-workbench .el-checkbox__input.is-indeterminate .el-checkbox__inner {
  background: #7c3aed !important;
  border-color: #7c3aed !important;
}
.ota-workbench .el-checkbox__input.is-checked .el-checkbox__inner::after {
  border-color: #fff !important;
}
.ota-workbench .el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
  background-color: #fff !important;
  height: 2px !important;
}
.ota-workbench .el-table .el-checkbox {
  height: auto !important;
}
</style>
