<script setup lang="ts">
import type { Tenant, TenantStatus } from '~/types/tenant'

const { data: tenants, refresh, pending } = await useFetch<Tenant[]>('/api/tenants', {
  default: () => [],
})

const search = ref('')
const statusFilter = ref<'all' | TenantStatus>('all')

const filtered = computed(() => {
  const q = search.value.trim().toLowerCase()
  return (tenants.value ?? []).filter((t) => {
    if (statusFilter.value !== 'all' && t.status !== statusFilter.value) return false
    if (!q) return true
    return t.slug.toLowerCase().includes(q) || t.name.toLowerCase().includes(q)
  })
})

const counts = computed(() => {
  const c = { all: 0, active: 0, pending: 0, suspended: 0, deleted: 0 }
  for (const t of tenants.value ?? []) {
    c.all++
    c[t.status]++
  }
  return c
})

const STATUS_TONE: Record<TenantStatus, 'ok' | 'warn' | 'bad' | 'neutral'> = {
  active: 'ok',
  pending: 'warn',
  suspended: 'bad',
  deleted: 'neutral',
}

function navTo(t: Tenant) {
  return navigateTo(`/tenants/${t.slug}`)
}

// ── Create modal ──────────────────────────────────────────────────────────
// Operator-created tenants are DIRECT customers (no partnerId — partner-owned
// tenants are created through the partner portal wizard instead). Attach to a
// partner later from the tenant detail page if needed.
const createOpen = ref(false)
const createBusy = ref(false)
const createError = ref<string | null>(null)
const form = reactive({
  slug: '',
  name: '',
  plan: 'mvp' as 'mvp' | 'pro' | 'enterprise',
  cycle: 'monthly' as 'monthly' | 'quarterly' | 'yearly',
  currency: 'DKK' as 'DKK' | 'EUR' | 'USD',
  seats: 5,
  domain: '',
  adminName: '',
  adminEmail: '',
})

function openCreate() {
  Object.assign(form, {
    slug: '',
    name: '',
    plan: 'mvp',
    cycle: 'monthly',
    currency: 'DKK',
    seats: 5,
    domain: '',
    adminName: '',
    adminEmail: '',
  })
  createError.value = null
  createOpen.value = true
}

async function submitCreate() {
  createBusy.value = true
  createError.value = null
  try {
    const domain = form.domain.trim().toLowerCase()
    const created = await $fetch<Tenant>('/api/tenants', {
      method: 'POST',
      body: {
        slug: form.slug.trim(),
        name: form.name.trim(),
        plan: form.plan,
        cycle: form.cycle,
        currency: form.currency,
        seats: form.seats,
        ...(domain ? { domains: [domain] } : {}),
        ...(form.adminName.trim() && form.adminEmail.trim()
          ? { adminName: form.adminName.trim(), adminEmail: form.adminEmail.trim() }
          : {}),
      },
    })
    createOpen.value = false
    await refresh()
    await navigateTo(`/tenants/${created.slug}`)
  } catch (err: unknown) {
    const e = err as { data?: { data?: { message?: string | string[] }; message?: string } }
    const msg = e.data?.data?.message ?? e.data?.message ?? String(err)
    createError.value = Array.isArray(msg) ? msg.join(' · ') : msg
  } finally {
    createBusy.value = false
  }
}
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Customers"
      title="Tenants"
      :subtitle="`${counts.all} tenants — ${counts.active} active, ${counts.pending} pending, ${counts.suspended} suspended.`"
    >
      <template #actions>
        <UiButton variant="secondary" :disabled="pending" @click="refresh()">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Refresh
        </UiButton>
        <UiButton variant="primary" @click="openCreate">
          <template #leading><UiIcon name="plus" :size="13" /></template>
          New tenant
        </UiButton>
      </template>
    </PageHeader>

    <div class="stage">
      <div class="filters">
        <div class="search">
          <UiIcon name="search" :size="14" stroke="var(--text-mute)" />
          <input v-model="search" placeholder="Search slug or name…" />
        </div>
        <div class="chips">
          <button
            v-for="opt in (['all', 'active', 'pending', 'suspended'] as const)"
            :key="opt"
            :class="['chip', { active: statusFilter === opt }]"
            @click="statusFilter = opt"
          >
            {{ opt }}
            <span class="chip-count">{{ counts[opt] }}</span>
          </button>
        </div>
      </div>

      <Card :pad="0">
        <table>
          <thead>
            <tr>
              <th>Tenant</th>
              <th>Status</th>
              <th>Plan</th>
              <th>Domains</th>
              <th>Created</th>
              <th class="th-right">Provisioning</th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="filtered.length === 0" class="empty">
              <td colspan="6">
                <div class="empty-inner">
                  <UiIcon name="building" :size="20" stroke="var(--text-mute)" />
                  <span>No tenants match this filter.</span>
                  <UiButton v-if="counts.all === 0" variant="ghost" size="sm" @click="openCreate">Create the first one</UiButton>
                </div>
              </td>
            </tr>
            <tr v-for="t in filtered" :key="t._id" class="clickable" @click="navTo(t)">
              <td>
                <div class="cell-tenant">
                  <div class="cell-name">{{ t.name }}</div>
                  <Mono dim>{{ t.slug }}</Mono>
                </div>
              </td>
              <td><Badge :tone="STATUS_TONE[t.status]" dot>{{ t.status }}</Badge></td>
              <td><Badge tone="neutral">{{ t.plan }}</Badge></td>
              <td>
                <Mono dim>{{ t.domains.length ? t.domains[0] : '—' }}</Mono>
                <Mono v-if="t.domains.length > 1" dim>(+{{ t.domains.length - 1 }})</Mono>
              </td>
              <td><Mono dim>{{ new Date(t.createdAt).toISOString().slice(0, 10) }}</Mono></td>
              <td class="td-right">
                <div class="prov-row">
                  <span
                    v-for="k in (['authentik', 'stalwart', 'ocis'] as const)"
                    :key="k"
                    :class="['prov', `prov-${t.provisioningStatus?.[k] ?? 'pending'}`]"
                    :title="`${k}: ${t.provisioningStatus?.[k] ?? 'pending'}`"
                  />
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </Card>
    </div>

    <ConfirmDialog
      :open="createOpen"
      eyebrow="New tenant"
      title="Create direct customer"
      confirm-label="Create"
      :busy="createBusy"
      @close="createOpen = false"
      @confirm="submitCreate"
    >
      <form class="form" @submit.prevent="submitCreate">
        <label>
          <span>Slug · URL-safe id</span>
          <input v-model="form.slug" placeholder="e.g. dezky" autocomplete="off" required />
        </label>
        <label>
          <span>Display name</span>
          <input v-model="form.name" placeholder="e.g. Dezky ApS" required />
        </label>
        <div class="form-row">
          <label>
            <span>Plan</span>
            <select v-model="form.plan">
              <option value="mvp">mvp</option>
              <option value="pro">pro</option>
              <option value="enterprise">enterprise</option>
            </select>
          </label>
          <label>
            <span>Cycle</span>
            <select v-model="form.cycle">
              <option value="monthly">monthly</option>
              <option value="quarterly">quarterly</option>
              <option value="yearly">yearly</option>
            </select>
          </label>
          <label>
            <span>Currency</span>
            <select v-model="form.currency">
              <option value="DKK">DKK</option>
              <option value="EUR">EUR</option>
              <option value="USD">USD</option>
            </select>
          </label>
          <label>
            <span>Seats</span>
            <input v-model.number="form.seats" type="number" min="0" max="10000" />
          </label>
        </div>
        <label>
          <span>Primary mail domain · optional</span>
          <input v-model="form.domain" placeholder="e.g. dezky.eu" autocomplete="off" />
        </label>
        <label>
          <span>First admin name · optional</span>
          <input v-model="form.adminName" placeholder="e.g. Ronni Baslund" />
        </label>
        <label>
          <span>First admin email · optional</span>
          <input v-model="form.adminEmail" type="email" placeholder="e.g. ronni@dezky.eu" />
        </label>
      </form>
      <p v-if="createError" class="err">{{ createError }}</p>
    </ConfirmDialog>
  </div>
</template>

<style scoped>
.stage {
  padding: 24px 40px 64px 40px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.filters {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
}

.search {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 34px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  flex: 1;
  max-width: 360px;
}
.search input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  min-width: 0;
}
.search input::placeholder { color: var(--text-mute); }

.chips { display: flex; gap: 4px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  cursor: pointer;
}
.chip:hover { background: var(--elevated); color: var(--text); }
.chip.active {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.chip-count {
  font-size: 10px;
  opacity: 0.6;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

thead tr {
  border-bottom: 1px solid var(--border);
}

th {
  padding: 12px 16px;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
}
th.th-right { text-align: right; }

tbody tr {
  border-bottom: 1px solid var(--border);
}
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--surface); }
tbody tr:last-child { border-bottom: none; }

td {
  padding: 14px 16px;
  color: var(--text);
}
td.td-right { text-align: right; }

.cell-tenant { display: flex; flex-direction: column; gap: 2px; }
.cell-name { font-weight: 500; font-size: 13px; }

.empty td { padding: 48px 16px; text-align: center; }
.empty-inner {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--text-mute);
  font-size: 13px;
}

.prov-row { display: inline-flex; gap: 4px; justify-content: flex-end; }
.prov {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--border);
}
.prov-ok { background: var(--ok); }
.prov-skipped { background: var(--text-mute); }
.prov-error { background: var(--bad); }
.prov-pending { background: var(--warn); }

.form { display: flex; flex-direction: column; gap: 12px; }
.form-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.form label { display: flex; flex-direction: column; gap: 6px; }
.form label span {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 500;
}
.form input,
.form select {
  height: 34px;
  padding: 0 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  outline: none;
}
.form input:focus,
.form select:focus { border-color: var(--accent); }

.err {
  margin: 12px 0 0 0;
  color: var(--bad);
  font-family: var(--font-mono);
  font-size: 12px;
}
</style>
