<script setup lang="ts">
// Add-domain wizard, wired to platform-api. 6 full-page steps:
//   1 Domain   — POST the domain (provisions it in Stalwart, which auto-creates
//                 DKIM keys and returns the records to publish + an ownership token)
//   2 Verify   — poll the ownership TXT until it resolves
//   3 Mail     — show + re-check the MX/SPF records
//   4 DKIM     — show + re-check the DKIM record(s)
//   5 DMARC    — pick a policy (PATCH) and re-check
//   6 Done     — summary of live status
// All record values come from the server; only the guidance copy is static.

import type { DmarcPolicy, DomainRecordView, DomainView, RecordKind, RecordStatus } from '~/composables/useDomains'

const router = useRouter()
const toast = useToast()
const { add, recheck, setDmarcPolicy } = useDomains()

const step = ref(1)
const domainInput = ref('')
const dv = ref<DomainView | null>(null)
const busy = ref(false)
const policy = ref<DmarcPolicy>('quarantine')
const steps = ['Domain', 'Verify', 'Mail', 'DKIM', 'DMARC', 'Done']

const domainName = computed(() => dv.value?.domain ?? domainInput.value)

type Tone = 'ok' | 'warn' | 'bad'
function tone(status: RecordStatus): Tone {
  return status === 'ok' ? 'ok' : status === 'warn' ? 'warn' : 'bad'
}
function recordsOfKind(kind: RecordKind): DomainRecordView[] {
  return dv.value?.records.filter((r) => r.kind === kind) ?? []
}
const ownershipRecord = computed(() => recordsOfKind('ownership')[0])
const ownershipOk = computed(() => dv.value?.checks.ownership === 'ok')

const policyOptions = [
  { v: 'none' as const,       l: 'none · monitor only',      d: 'Reports failures but never blocks. Use only for the first 2 weeks while you confirm legitimate mail flows.' },
  { v: 'quarantine' as const, l: 'quarantine · recommended', d: 'Suspicious mail goes to spam. Catches almost all spoofing without breaking legitimate edge cases.' },
  { v: 'reject' as const,     l: 'reject · strictest',       d: "Suspicious mail is bounced. Use after you've been at quarantine for 30+ days with no surprises." },
]

function toastError(err: unknown, title: string) {
  const e = err as { data?: { message?: string | string[] }; message?: string }
  const msg = e?.data?.message ?? e?.message ?? 'Unknown error'
  toast.bad(title, Array.isArray(msg) ? msg.join(', ') : msg)
}

// Step 1 → create the domain.
async function createDomain() {
  const name = domainInput.value.trim().toLowerCase()
  if (!name) return
  busy.value = true
  try {
    dv.value = await add(name)
    step.value = 2
  } catch (err) {
    toastError(err, 'Could not add domain')
  } finally {
    busy.value = false
  }
}

// Re-run DNS checks and refresh the wizard's domain snapshot.
async function recheckNow() {
  if (!dv.value) return
  busy.value = true
  try {
    dv.value = await recheck(dv.value.domain)
  } catch (err) {
    toastError(err, 'Could not re-check')
  } finally {
    busy.value = false
  }
}

// Step 5 → persist the DMARC policy, then finish.
async function finishWithDmarc() {
  if (!dv.value) { step.value = 6; return }
  busy.value = true
  try {
    dv.value = await setDmarcPolicy(dv.value.domain, policy.value)
    step.value = 6
  } catch (err) {
    toastError(err, 'Could not set DMARC policy')
  } finally {
    busy.value = false
  }
}

// While on the Verify step, poll for the ownership TXT every 10s until it lands.
let pollTimer: ReturnType<typeof setInterval> | null = null
function stopPoll() { if (pollTimer) { clearInterval(pollTimer); pollTimer = null } }
watch([step, ownershipOk], ([s, ok]) => {
  stopPoll()
  if (s === 2 && !ok) {
    pollTimer = setInterval(() => { if (!busy.value) recheckNow() }, 10000)
  }
})
onBeforeUnmount(stopPoll)

function cancel() { router.push('/admin/domains') }
function done() { router.push('/admin/domains') }
</script>

<template>
  <div class="wizard">
    <div class="flow-head">
      <div class="row top">
        <div class="left">
          <button v-if="step > 1 && step < 6" class="back" @click="step--">
            <UiIcon name="chevLeft" :size="12" /> back
          </button>
          <Eyebrow>Add domain</Eyebrow>
        </div>
        <button class="cancel" @click="cancel">
          <UiIcon name="x" :size="14" /> cancel
        </button>
      </div>
      <div class="row title-row">
        <h1>{{ step < 6 ? 'Verify and configure your domain' : `${domainName} is ready` }}</h1>
        <Mono dim>Step {{ step }} of 6</Mono>
      </div>
      <div class="rail">
        <div v-for="(s, i) in steps" :key="s" class="rail-cell">
          <div class="bar" :class="i + 1 < step ? 'done' : i + 1 === step ? 'active' : 'todo'" />
          <div class="rail-label">
            <Mono dim>0{{ i + 1 }}</Mono>
            <span :class="i + 1 === step ? 'is-active' : i + 1 < step ? 'is-done' : 'is-todo'">{{ s }}</span>
          </div>
        </div>
      </div>
    </div>

    <div class="body">
      <!-- Step 1: Domain -->
      <div v-if="step === 1" class="step1">
        <p class="lead">
          Enter the domain you'll use for mail and identity. You'll need to add a few DNS records to prove you own it and route mail correctly.
        </p>
        <label class="field">
          <Eyebrow>Domain</Eyebrow>
          <div class="input-wrap">
            <UiIcon name="globe" :size="14" stroke="var(--text-mute)" />
            <input v-model="domainInput" placeholder="acme.dk" @keyup.enter="createDomain" />
          </div>
        </label>
        <div class="info-box">
          <Eyebrow>Need to know</Eyebrow>
          <div class="info-body">
            • DNS changes typically propagate in 5–30 minutes<br />
            • You'll need access to your domain's DNS provider (Cloudflare, GoDaddy, etc.)<br />
            • For Danish .dk domains, you'll work with <Mono>DK-Hostmaster</Mono> or your registrar
          </div>
        </div>
      </div>

      <!-- Step 2: Verify ownership -->
      <div v-else-if="step === 2" class="step2">
        <p class="lead">
          Add this TXT record to <Mono>{{ domainName }}</Mono>. We check every 10 seconds until it appears.
        </p>
        <div v-if="ownershipRecord" class="dns-rows">
          <div class="dns-row">
            <div><Mono dim>TYPE</Mono><div class="dns-val">{{ ownershipRecord.type }}</div></div>
            <div><Mono dim>HOST</Mono><div class="dns-val">{{ ownershipRecord.fqdn }}</div></div>
            <div><Mono dim>VALUE</Mono><div class="dns-val dim">{{ ownershipRecord.expected }}</div></div>
            <div class="dns-right">
              <Badge :tone="ownershipOk ? 'ok' : 'warn'" dot>{{ ownershipOk ? 'verified' : 'pending' }}</Badge>
            </div>
          </div>
        </div>
        <div class="banner" :class="ownershipOk ? 'ok' : 'warn'">
          <UiIcon :name="ownershipOk ? 'check' : 'refresh'" :size="14" :stroke="ownershipOk ? 'var(--ok)' : 'var(--warn)'" />
          <div class="banner-body">
            <div class="banner-title">{{ ownershipOk ? 'Ownership verified' : 'Waiting for the TXT record' }}</div>
            <div class="banner-text">
              {{ ownershipOk
                ? 'We found the verification record. Continue to set up mail.'
                : 'Add the record above, then click verify — or wait, we re-check automatically every 10 seconds.' }}
            </div>
          </div>
          <UiButton size="sm" variant="primary" :disabled="busy" @click="recheckNow">{{ busy ? 'Checking…' : 'Verify now' }}</UiButton>
        </div>
      </div>

      <!-- Step 3: Mail (MX + SPF) -->
      <div v-else-if="step === 3" class="step3">
        <p class="lead">
          Add these records so mail to <Mono>@{{ domainName }}</Mono> reaches dezky and outgoing mail is trusted.
        </p>
        <Eyebrow style="display: block; margin-top: 20px; margin-bottom: 10px">MX · inbound</Eyebrow>
        <div class="dns-rows">
          <RecordRow v-for="(r, i) in recordsOfKind('mx')" :key="'mx' + i" :rec="r" />
          <div v-if="!recordsOfKind('mx').length" class="empty-note">No MX record yet — re-check after mail provisioning completes.</div>
        </div>
        <Eyebrow style="display: block; margin-top: 24px; margin-bottom: 10px">SPF · sender policy</Eyebrow>
        <div class="dns-rows">
          <RecordRow v-for="(r, i) in recordsOfKind('spf')" :key="'spf' + i" :rec="r" />
        </div>
        <div class="banner" :class="dv && dv.checks.mx === 'ok' && dv.checks.spf === 'ok' ? 'ok' : 'warn'">
          <UiIcon :name="dv && dv.checks.mx === 'ok' && dv.checks.spf === 'ok' ? 'check' : 'refresh'" :size="14" :stroke="dv && dv.checks.mx === 'ok' && dv.checks.spf === 'ok' ? 'var(--ok)' : 'var(--warn)'" />
          <div class="banner-body">
            <div class="banner-title">{{ dv && dv.checks.mx === 'ok' && dv.checks.spf === 'ok' ? 'Mail routing verified' : 'Waiting for MX / SPF' }}</div>
            <div class="banner-text">Add the records above. You can continue now and re-check from the Domains page later.</div>
          </div>
          <UiButton size="sm" variant="secondary" :disabled="busy" @click="recheckNow">{{ busy ? 'Checking…' : 'Re-check' }}</UiButton>
        </div>
      </div>

      <!-- Step 4: DKIM -->
      <div v-else-if="step === 4" class="step4">
        <p class="lead">
          DKIM signs every outgoing email so Gmail and Outlook trust it. We rotate the keys for you automatically.
        </p>
        <Eyebrow style="display: block; margin-top: 20px; margin-bottom: 10px">DKIM · message signing</Eyebrow>
        <div class="dns-rows">
          <RecordRow v-for="(r, i) in recordsOfKind('dkim')" :key="'dkim' + i" :rec="r" />
          <div v-if="!recordsOfKind('dkim').length" class="empty-note">No DKIM record yet — re-check after mail provisioning completes.</div>
        </div>
        <div class="banner" :class="dv && dv.checks.dkim === 'ok' ? 'ok' : 'warn'">
          <UiIcon :name="dv && dv.checks.dkim === 'ok' ? 'check' : 'refresh'" :size="14" :stroke="dv && dv.checks.dkim === 'ok' ? 'var(--ok)' : 'var(--warn)'" />
          <div class="banner-body">
            <div class="banner-title">{{ dv && dv.checks.dkim === 'ok' ? 'DKIM is signing' : 'Waiting for DKIM' }}</div>
            <div class="banner-text">Publish the record(s) above. Both selectors must be present for full coverage.</div>
          </div>
          <UiButton size="sm" variant="secondary" :disabled="busy" @click="recheckNow">{{ busy ? 'Checking…' : 'Re-check' }}</UiButton>
        </div>
      </div>

      <!-- Step 5: DMARC -->
      <div v-else-if="step === 5" class="step5">
        <p class="lead">
          DMARC tells receiving servers what to do with email that fails authentication. We strongly recommend at least <Mono>quarantine</Mono>.
        </p>
        <Eyebrow style="display: block; margin-top: 20px; margin-bottom: 10px">Choose policy</Eyebrow>
        <div class="policy-list">
          <label v-for="p in policyOptions" :key="p.v" :class="{ active: policy === p.v }">
            <span class="radio-dot"><span v-if="policy === p.v" /></span>
            <input type="radio" :value="p.v" v-model="policy" />
            <div>
              <div class="policy-label">{{ p.l }}</div>
              <div class="policy-d">{{ p.d }}</div>
            </div>
          </label>
        </div>
        <Eyebrow style="display: block; margin-top: 24px; margin-bottom: 10px">Add this record</Eyebrow>
        <div class="dns-rows">
          <div class="dns-row">
            <div><Mono dim>TYPE</Mono><div class="dns-val">TXT</div></div>
            <div><Mono dim>HOST</Mono><div class="dns-val">_dmarc.{{ domainName }}</div></div>
            <div><Mono dim>VALUE</Mono><div class="dns-val dim">v=DMARC1; p={{ policy }}; rua=mailto:postmaster@{{ domainName }}</div></div>
            <div class="dns-right">
              <Badge :tone="dv && dv.checks.dmarc === 'ok' ? 'ok' : 'warn'" dot>{{ dv ? dv.checks.dmarc : 'pending' }}</Badge>
            </div>
          </div>
        </div>
      </div>

      <!-- Step 6: Done -->
      <div v-else class="step6">
        <div class="check-badge">
          <UiIcon name="check" :size="36" :stroke-width="2.5" />
        </div>
        <h2>{{ domainName }} is connected.</h2>
        <p class="lead-center">
          The domain is provisioned. Publish any remaining DNS records and they'll go green automatically — you can track status from the Domains page.
        </p>
        <div v-if="dv" class="summary-grid">
          <div v-for="k in (['mx','spf','dkim','dmarc'] as const)" :key="k" class="summary-cell">
            <Badge :tone="dv.checks[k] === 'ok' ? 'ok' : 'warn'" dot>{{ dv.checks[k] }}</Badge>
            <Mono>{{ k.toUpperCase() }}</Mono>
          </div>
        </div>
      </div>
    </div>

    <div class="footer">
      <template v-if="step < 6">
        <UiButton variant="ghost" @click="cancel">Save and exit</UiButton>
        <div class="spacer" />
        <UiButton v-if="step === 5" variant="secondary" :disabled="busy" @click="step = 6">Skip DMARC for now</UiButton>
        <UiButton
          v-if="step === 1"
          variant="primary"
          :disabled="busy || !domainInput.trim()"
          @click="createDomain"
        >
          {{ busy ? 'Adding…' : 'Continue' }}
          <template #trailing><UiIcon name="arrowRight" :size="13" /></template>
        </UiButton>
        <UiButton
          v-else-if="step === 2"
          variant="primary"
          :disabled="!ownershipOk"
          @click="step = 3"
        >
          {{ ownershipOk ? 'Verified · continue' : 'Waiting for verification' }}
          <template #trailing><UiIcon name="arrowRight" :size="13" /></template>
        </UiButton>
        <UiButton v-else-if="step === 5" variant="primary" :disabled="busy" @click="finishWithDmarc">
          <template #leading><UiIcon name="check" :size="13" /></template>
          {{ busy ? 'Saving…' : 'Add DMARC & finish' }}
        </UiButton>
        <UiButton v-else variant="primary" @click="step++">
          Continue
          <template #trailing><UiIcon name="arrowRight" :size="13" /></template>
        </UiButton>
      </template>
      <template v-else>
        <div class="spacer" />
        <UiButton variant="secondary" @click="done">
          <template #leading><UiIcon name="users" :size="13" /></template>
          Invite users on this domain
        </UiButton>
        <UiButton variant="primary" @click="done">Back to domains</UiButton>
      </template>
    </div>
  </div>
</template>

<style scoped>
.wizard { display: flex; flex-direction: column; min-height: 100%; }

.flow-head { border-bottom: 1px solid var(--border); }
.row { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.row.top { padding: 14px 32px; }
.row.title-row { padding: 0 32px 18px 32px; align-items: flex-end; }
.left { display: flex; align-items: center; gap: 14px; }
.back, .cancel {
  background: transparent;
  border: none;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-mute);
  font-size: 12px;
  cursor: pointer;
  font-family: var(--font-mono);
}
.cancel { padding: 6px; font-family: inherit; }
.row.title-row h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 28px;
  letter-spacing: -0.025em;
  margin: 0;
  line-height: 1.05;
}
.rail { padding: 0 32px 18px 32px; display: flex; gap: 6px; }
.rail-cell { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.bar { height: 3px; border-radius: 2px; }
.bar.done { background: var(--text); }
.bar.active { background: var(--accent); }
.bar.todo { background: var(--border); }
.rail-label { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.is-active { font-weight: 600; color: var(--text); }
.is-done { color: var(--text); }
.is-todo { color: var(--text-mute); }

.body { flex: 1; padding: 24px 32px; max-width: 920px; margin: 0 auto; width: 100%; }
.lead { color: var(--text-dim); font-size: 14px; line-height: 1.6; margin-top: 0; }
.lead-center { color: var(--text-dim); font-size: 15px; line-height: 1.6; margin-top: 12px; max-width: 500px; margin-inline: auto; }

.field { display: flex; flex-direction: column; gap: 6px; max-width: 520px; }
.input-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 36px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.input-wrap input { flex: 1; border: none; outline: none; background: transparent; font-family: inherit; font-size: 13px; color: var(--text); }

.info-box {
  margin-top: 18px;
  padding: 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  max-width: 520px;
}
.info-body { margin-top: 10px; font-size: 13px; color: var(--text-dim); line-height: 1.65; }

.dns-rows { display: flex; flex-direction: column; gap: 8px; }
.dns-row {
  display: grid;
  grid-template-columns: 80px 220px 1fr 90px;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.dns-val { font-family: var(--font-mono); font-size: 13px; font-weight: 600; margin-top: 2px; }
.dns-val.dim { color: var(--text-dim); font-weight: 400; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dns-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.empty-note { font-size: 12px; color: var(--text-mute); padding: 10px 2px; font-family: var(--font-mono); }

.banner {
  margin-top: 16px;
  padding: 14px;
  border-radius: 6px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.banner.warn { background: rgba(232, 154, 31, 0.06); border: 1px solid rgba(232, 154, 31, 0.24); border-left: 3px solid var(--warn); }
.banner.ok   { background: rgba(31, 138, 91, 0.06); border: 1px solid rgba(31, 138, 91, 0.24); border-left: 3px solid var(--ok); }
.banner-body { flex: 1; font-size: 13px; }
.banner-title { font-weight: 600; }
.banner-text { color: var(--text-dim); margin-top: 4px; line-height: 1.5; }

.policy-list { display: flex; flex-direction: column; gap: 8px; }
.policy-list label {
  display: flex;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 6px;
  cursor: pointer;
}
.policy-list label.active { background: var(--bg); border-color: var(--text); }
.policy-list input { display: none; }
.radio-dot {
  width: 16px;
  height: 16px;
  border-radius: 999px;
  border: 2px solid var(--border-hi, var(--border));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 2px;
}
.policy-list label.active .radio-dot { border-color: var(--text); }
.radio-dot span { width: 7px; height: 7px; border-radius: 999px; background: var(--text); }
.policy-label { font-size: 13px; font-weight: 600; }
.policy-d { font-size: 12px; color: var(--text-mute); margin-top: 4px; line-height: 1.5; }

.step6 { max-width: 680px; text-align: center; padding: 60px 0; margin: 0 auto; }
.check-badge {
  width: 72px;
  height: 72px;
  border-radius: 16px;
  background: var(--accent);
  color: var(--accent-fg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 24px;
}
.step6 h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 36px;
  letter-spacing: -0.025em;
  margin: 0;
  line-height: 1.05;
}
.summary-grid {
  display: inline-grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-top: 36px;
  padding: 16px 24px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  text-align: left;
}
.summary-cell { display: flex; align-items: center; gap: 6px; }

.footer {
  border-top: 1px solid var(--border);
  padding: 14px 32px;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  position: sticky;
  bottom: 0;
}
.spacer { flex: 1; }
</style>
