<template>
  <!-- Generic renderer for ADR-010 get_asset_panels (Path A). A plugin declares
       a panel as JSON (title, endpoint, render mode, field map); this renders it
       on any asset detail page, so a plugin adds detail-page UI with no Vue. -->
  <template v-for="panel in panels" :key="panel.id">
    <div v-if="panelVisible(panel)" class="section-card">
      <h3 class="section-title">{{ panel.title }}</h3>

      <!-- list: items each with a title, optional status badge, meta lines -->
      <div v-if="panel.render === 'list'" class="pap-list">
        <template v-if="rows(panel).length">
          <div v-for="(item, index) in rows(panel)" :key="index" class="pap-item">
            <div class="pap-item-top">
              <span class="pap-title">{{ mapTitle(panel, item) }}</span>
              <span v-if="mapBadge(panel, item)" class="status-badge"
                    :style="colorStyle(mapBadge(panel, item).color)">
                {{ mapBadge(panel, item).label }}
              </span>
            </div>
            <div v-if="mapMeta(panel, item).length" class="pap-meta">
              <span v-for="(m, mi) in mapMeta(panel, item)" :key="mi"
                    :class="{ mono: m.mono }">{{ m.text }}</span>
            </div>
          </div>
          <router-link v-if="panel.manage" :to="manageLink(panel, assetid)" class="pap-manage">
            {{ panel.manage.label || 'Manage' }}
          </router-link>
        </template>
        <div v-else class="pap-empty">
          <span class="muted">{{ panel.empty || 'Nothing to show.' }}</span>
          <router-link v-if="panel.manage" :to="manageLink(panel, assetid)" class="pap-manage">
            {{ panel.manage.emptylabel || panel.manage.label || 'Add' }}
          </router-link>
        </div>
      </div>

      <!-- tabs: several label/value sections, one visible at a time. Keeps a
           panel with many fields to the height of its largest section - a
           30-row card cannot be split by the two-column multicol layout and
           drags one column far past the other. -->
      <div v-else-if="panel.render === 'tabs'" class="pap-tabs">
        <div class="pap-tabstrip" role="tablist">
          <button
            v-for="(section, si) in tabSections(panel)"
            :key="si"
            type="button"
            role="tab"
            class="pap-tab"
            :class="{ on: si === activeTab(panel) }"
            :aria-selected="si === activeTab(panel)"
            @click="setTab(panel, si)"
          >{{ section.label }}</button>
        </div>
        <div class="pap-kv">
          <div
            v-for="(field, fi) in (tabSections(panel)[activeTab(panel)] || {}).fields || []"
            :key="fi"
            class="pap-kv-row"
          >
            <span class="pap-kv-label">{{ field.label }}</span>
            <span class="pap-kv-value" :class="{ mono: field.mono }">{{ field.value }}</span>
          </div>
        </div>
      </div>

      <!-- keyvalue: a label/value grid -->
      <div v-else-if="panel.render === 'keyvalue'" class="pap-kv">
        <div v-for="(field, fi) in keyvalueFields(panel)" :key="fi" class="pap-kv-row">
          <span class="pap-kv-label">{{ field.label }}</span>
          <span class="pap-kv-value" :class="{ mono: field.mono }">{{ field.value }}</span>
        </div>
      </div>

      <!-- table: columns declared by the panel (or inferred from row keys) -->
      <div v-else-if="panel.render === 'table'" class="pap-table-wrap">
        <table class="pap-table">
          <thead>
            <tr><th v-for="col in tableColumns(panel)" :key="col.key">{{ col.label }}</th></tr>
          </thead>
          <tbody>
            <tr v-for="(row, ri) in rows(panel)" :key="ri">
              <td v-for="col in tableColumns(panel)" :key="col.key">{{ cell(row, col) }}</td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- badge: a row of colored badges -->
      <div v-else-if="panel.render === 'badge'" class="pap-badges">
        <span v-for="(b, bi) in badges(panel)" :key="bi" class="status-badge"
              :style="colorStyle(b.color)">{{ b.label }}</span>
      </div>
    </div>
  </template>
</template>

<script setup>
import { ref, watch } from 'vue'
import api from '../api'
import { colorStyle } from '@/utils/colorStyle'
import {
  toApiPath, rows, panelVisible, mapTitle, mapBadge, mapMeta, manageLink,
  keyvalueFields, tableColumns, cell, badges, tabSections,
} from './pluginAssetPanels'

const props = defineProps({
  assetid: { type: [Number, String], default: null },
})

const panels = ref([])

// Which tab each 'tabs' panel is showing, keyed by panel id. Kept here rather
// than on the panel object because panels are replaced wholesale on refetch.
const tabs = ref({})
function activeTab(panel) { return tabs.value[panel.id] || 0 }
function setTab(panel, index) { tabs.value = { ...tabs.value, [panel.id]: index } }

// Fetch the declared panels for this asset, then each panel's data endpoint.
async function load() {
  panels.value = []
  if (!props.assetid) return
  let declared
  try {
    const response = await api.get('/pluginui/asset-panels', {
      params: { assetid: props.assetid },
    })
    declared = response.data.data || []
  } catch (err) {
    return
  }
  const withData = await Promise.all(
    declared.map(async (panel) => {
      try {
        const response = await api.get(toApiPath(panel.endpoint, props.assetid))
        return { ...panel, _data: response.data.data }
      } catch (err) {
        return { ...panel, _data: null }
      }
    })
  )
  panels.value = withData
}

watch(() => props.assetid, load, { immediate: true })
</script>

<style scoped>
.pap-list { display: flex; flex-direction: column; gap: 0.75rem; }
.pap-item { padding: 0.6rem 0.75rem; background: var(--bg); border-radius: 6px; }
.pap-item-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.pap-title { font-weight: 600; color: var(--text); }
.status-badge { padding: 0.15rem 0.6rem; border-radius: 12px; font-size: 0.75rem; font-weight: 600; }
.pap-meta { margin-top: 0.35rem; display: flex; flex-wrap: wrap; gap: 0.75rem; font-size: 0.82rem; color: var(--text-light); }
.pap-empty { display: flex; align-items: center; gap: 0.6rem; }
.pap-manage { font-size: 0.82rem; }
/* Two aligned columns rather than space-between: a ragged right edge is hard
   to scan once a panel carries more than a handful of rows, and a long value
   (a UNC path) otherwise pushes its label away from the others. */
.pap-kv { display: grid; grid-template-columns: minmax(7rem, auto) 1fr; gap: 0.35rem 1rem; align-items: baseline; }
.pap-kv-row { display: contents; }
.pap-kv-label { color: var(--text-light); }
.pap-kv-value { color: var(--text); font-weight: 500; overflow-wrap: anywhere; }
/* Tab strip: a quiet segmented control, not browser-default buttons. The
   active tab is marked by an underline AND weight, so it does not rely on
   colour alone. */
.pap-tabstrip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  margin-bottom: 0.85rem;
  border-bottom: 1px solid var(--border);
}
.pap-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 0.35rem 0.7rem;
  color: var(--text-light);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}
.pap-tab:hover { color: var(--text); }
.pap-tab.on {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: 700;
}

.pap-table-wrap { overflow-x: auto; }
.pap-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.pap-table th, .pap-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border); }
.pap-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.mono { font-family: monospace; }
.muted { color: var(--text-light); }
</style>
