<script setup lang="ts">
// Mail settings. The per-tenant parts are real: Aliases (extra addresses that
// route to a mailbox) and Distribution lists (one address → many recipients),
// both backed by Stalwart via /api/tenants/:slug/mail/*. The other three tabs —
// Forwarding, Filters, Compliance — are server-global in Stalwart (one shared
// spam engine / retention policy), so they're operator-managed, not per-customer;
// they render an honest "managed by Dezky" state rather than fake controls.

import type { TenantUserDoc } from '~/types/workspace'

interface AliasView {
  address: string
  localPart: string
  domain: string
  destination: string
  accountId: string
  enabled: boolean
}
interface ListView {
  id: string
  name: string
  address: string
  domain: string
  recipients: string[]
  members: number
  description?: string
}
interface DomainLite { id: string; domain: string; isPrimary: boolean }

const toast = useToast()
const { tenant } = useTenant()
const slug = computed(() => tenant.value?.slug ?? '')
const { request } = useApiFetch()

const tab = ref<'aliases' | 'lists' | 'forwarding' | 'filters' | 'compliance'>('aliases')

const { data: aliases, refresh: refreshAliases } = await useFetch<AliasView[]>(
  () => `/api/tenants/${slug.value}/mail/aliases`,
  { key: 'mail-aliases', default: () => [], immediate: !!slug.value, watch: [slug] },
)
const { data: lists, refresh: refreshLists } = await useFetch<ListView[]>(
  () => `/api/tenants/${slug.value}/mail/lists`,
  { key: 'mail-lists', default: () => [], immediate: !!slug.value, watch: [slug] },
)
const { data: domains } = await useFetch<DomainLite[]>(
  () => `/api/tenants/${slug.value}/domains`,
  { key: 'mail-domains', default: () => [], immediate: !!slug.value, watch: [slug] },
)
const { data: users } = await useFetch<TenantUserDoc[]>(
  () => `/api/tenants/${slug.value}/users`,
  { key: 'mail-users', default: () => [], immediate: !!slug.value, watch: [slug] },
)

const primaryDomain = computed(() => domains.value?.find((d) => d.isPrimary) ?? domains.value?.[0])
// Only users with a real mailbox can be an alias destination.
const mailboxUsers = computed(() => (users.value ?? []).filter((u) => !!u.mailboxAddress))

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

const tabs = computed(() => [
  { value: 'aliases', label: 'Aliases', count: aliases.value?.length ?? 0 },
  { value: 'lists', label: 'Distribution lists', count: lists.value?.length ?? 0 },
  { value: 'forwarding', label: 'Forwarding' },
  { value: 'filters', label: 'Filters · anti-spam' },
  { value: 'compliance', label: 'Compliance · retention' },
])

// ── Aliases ──
const aliasOpen = ref(false)
const aliasBusy = ref(false)
const aliasForm = reactive({ localPart: '', domain: '', destinationUserId: '' })
const aliasDeleteTarget = ref<AliasView | null>(null)
const aliasDeleting = ref(false)

function openAlias() {
  aliasForm.localPart = ''
  aliasForm.domain = primaryDomain.value?.domain ?? ''
  aliasForm.destinationUserId = mailboxUsers.value[0]?._id ?? ''
  aliasOpen.value = true
}
async function submitAlias() {
  if (!aliasForm.localPart.trim() || !aliasForm.domain || !aliasForm.destinationUserId) return
  aliasBusy.value = true
  try {
    await request(`/api/tenants/${slug.value}/mail/aliases`, { method: 'POST', body: { ...aliasForm } })
    await refreshAliases()
    toast.ok('Alias created')
    aliasOpen.value = false
  } catch (err) {
    toastErr(err, 'Could not create alias')
  } finally {
    aliasBusy.value = false
  }
}
async function confirmDeleteAlias() {
  const a = aliasDeleteTarget.value
  if (!a) return
  aliasDeleting.value = true
  try {
    await request(`/api/tenants/${slug.value}/mail/aliases/${encodeURIComponent(a.address)}`, { method: 'DELETE' })
    await refreshAliases()
    toast.ok('Alias deleted', a.address)
    aliasDeleteTarget.value = null
  } catch (err) {
    toastErr(err, 'Could not delete alias')
  } finally {
    aliasDeleting.value = false
  }
}
function copyText(t: string) {
  if (typeof navigator !== 'undefined' && navigator.clipboard) navigator.clipboard.writeText(t)
  toast.ok('Copied to clipboard')
}

// ── Distribution lists ──
const listOpen = ref(false)
const listBusy = ref(false)
const listForm = reactive({ localPart: '', domain: '', description: '', recipientsText: '' })
const openList = ref<ListView | null>(null)
const manageText = ref('')
const manageBusy = ref(false)
const listDeleteTarget = ref<ListView | null>(null)
const listDeleting = ref(false)

function parseRecipients(text: string): string[] {
  return [...new Set(text.split(/[\s,;]+/).map((s) => s.trim().toLowerCase()).filter(Boolean))]
}
function openListCreate() {
  listForm.localPart = ''
  listForm.domain = primaryDomain.value?.domain ?? ''
  listForm.description = ''
  listForm.recipientsText = ''
  listOpen.value = true
}
async function submitList() {
  if (!listForm.localPart.trim() || !listForm.domain) return
  listBusy.value = true
  try {
    await request(`/api/tenants/${slug.value}/mail/lists`, {
      method: 'POST',
      body: {
        localPart: listForm.localPart.trim(),
        domain: listForm.domain,
        description: listForm.description.trim() || undefined,
        recipients: parseRecipients(listForm.recipientsText),
      },
    })
    await refreshLists()
    toast.ok('List created')
    listOpen.value = false
  } catch (err) {
    toastErr(err, 'Could not create list')
  } finally {
    listBusy.value = false
  }
}
function manage(l: ListView) {
  openList.value = l
  manageText.value = l.recipients.join('\n')
}
async function saveList() {
  const l = openList.value
  if (!l) return
  manageBusy.value = true
  try {
    await request(`/api/tenants/${slug.value}/mail/lists/${l.id}`, {
      method: 'PATCH',
      body: { recipients: parseRecipients(manageText.value) },
    })
    await refreshLists()
    toast.ok('Members saved', l.address)
    openList.value = null
  } catch (err) {
    toastErr(err, 'Could not save members')
  } finally {
    manageBusy.value = false
  }
}
async function confirmDeleteList() {
  const l = listDeleteTarget.value
  if (!l) return
  listDeleting.value = true
  try {
    await request(`/api/tenants/${slug.value}/mail/lists/${l.id}`, { method: 'DELETE' })
    await refreshLists()
    toast.ok('List deleted', l.address)
    listDeleteTarget.value = null
    openList.value = null
  } catch (err) {
    toastErr(err, 'Could not delete list')
  } finally {
    listDeleting.value = false
  }
}

const hasDomain = computed(() => (domains.value?.length ?? 0) > 0)
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Workspace"
      title="Mail settings"
      subtitle="Aliases and distribution lists for your domains. Spam filtering and retention are managed by Dezky."
    />
    <div class="tab-wrap">
      <Tabs v-model="tab" :items="tabs" />
    </div>

    <div class="content">
      <!-- ALIASES -->
      <template v-if="tab === 'aliases'">
        <div class="row">
          <div class="lead">Aliases route mail to an existing mailbox. They count against your domain, not your seats.</div>
          <UiButton variant="primary" :disabled="!hasDomain || mailboxUsers.length === 0" @click="openAlias">
            <template #leading><UiIcon name="plus" :size="14" /></template>
            Add alias
          </UiButton>
        </div>
        <Card v-if="!hasDomain" class="notice"><UiIcon name="globe" :size="18" stroke="var(--text-mute)" /> Add a domain first to create aliases.</Card>
        <Card v-else-if="(aliases?.length ?? 0) === 0" class="notice"><UiIcon name="mail" :size="18" stroke="var(--text-mute)" /> No aliases yet. Add one to route extra addresses to a mailbox.</Card>
        <Card v-else :pad="0">
          <table class="tbl">
            <thead><tr><th>Alias</th><th></th><th>Delivers to</th><th>State</th><th></th></tr></thead>
            <tbody>
              <tr v-for="a in aliases" :key="a.address">
                <td><Mono style="font-weight: 500">{{ a.address }}</Mono></td>
                <td><UiIcon name="arrowRight" :size="12" stroke="var(--text-mute)" /></td>
                <td><Mono dim>{{ a.destination }}</Mono></td>
                <td><Badge :tone="a.enabled ? 'ok' : 'neutral'" dot>{{ a.enabled ? 'active' : 'paused' }}</Badge></td>
                <td class="right">
                  <UiButton size="sm" variant="ghost" @click="copyText(a.address)"><UiIcon name="copy" :size="13" /></UiButton>
                  <UiButton size="sm" variant="ghost" @click="aliasDeleteTarget = a"><UiIcon name="trash" :size="13" /></UiButton>
                </td>
              </tr>
            </tbody>
          </table>
        </Card>
      </template>

      <!-- DISTRIBUTION LISTS -->
      <template v-else-if="tab === 'lists'">
        <div class="row">
          <div class="lead">Distribution lists send mail to many recipients via a single address. Members can be any email address.</div>
          <UiButton variant="primary" :disabled="!hasDomain" @click="openListCreate">
            <template #leading><UiIcon name="plus" :size="14" /></template>
            New list
          </UiButton>
        </div>
        <Card v-if="!hasDomain" class="notice"><UiIcon name="globe" :size="18" stroke="var(--text-mute)" /> Add a domain first to create lists.</Card>
        <Card v-else-if="(lists?.length ?? 0) === 0" class="notice"><UiIcon name="users" :size="18" stroke="var(--text-mute)" /> No distribution lists yet.</Card>
        <div v-else class="lists">
          <Card v-for="l in lists" :key="l.id">
            <div class="list-head">
              <div>
                <div class="list-title"><UiIcon name="users" :size="16" stroke="var(--text-mute)" /><span class="list-name">{{ l.name }}</span></div>
                <Mono dim style="display: block; margin-top: 4px">{{ l.address }}</Mono>
              </div>
              <Badge tone="neutral">{{ l.members }} member{{ l.members === 1 ? '' : 's' }}</Badge>
            </div>
            <div v-if="l.description" class="list-desc">{{ l.description }}</div>
            <div class="list-row">
              <UiButton size="sm" variant="secondary" @click="manage(l)">Manage members</UiButton>
              <UiButton size="sm" variant="ghost" @click="listDeleteTarget = l"><template #leading><UiIcon name="trash" :size="13" /></template>Delete</UiButton>
            </div>
          </Card>
        </div>
      </template>

      <!-- FORWARDING / FILTERS / COMPLIANCE — platform-managed -->
      <template v-else>
        <Card class="managed">
          <UiIcon name="shield" :size="28" stroke="var(--text-mute)" />
          <div class="managed-title">{{ tab === 'forwarding' ? 'Forwarding rules' : tab === 'filters' ? 'Spam & content filtering' : 'Compliance & retention' }} are managed by Dezky</div>
          <div class="managed-body">
            <template v-if="tab === 'forwarding'">
              Conditional forwarding runs on the shared mail platform. To route addresses today, use <strong>Aliases</strong> (one address → a mailbox) or <strong>Distribution lists</strong> (one address → many). Rule-based forwarding is on the roadmap.
            </template>
            <template v-else-if="tab === 'filters'">
              Inbound mail passes through Dezky's reputation engine and Bayesian spam filter — tuned and updated centrally for every workspace. Per-workspace filter rules aren't configurable here.
            </template>
            <template v-else>
              Mail retention and legal-hold policies are applied platform-wide for EU compliance. Contact Dezky to adjust retention for your organisation.
            </template>
          </div>
        </Card>
      </template>
    </div>

    <!-- Add alias modal -->
    <Modal :open="aliasOpen" eyebrow="Mail · aliases" title="Add alias" size="md" @close="aliasOpen = false">
      <div class="form-stack">
        <label class="field"><Eyebrow>Alias address</Eyebrow>
          <div class="alias-row">
            <input class="input" v-model="aliasForm.localPart" placeholder="sales" />
            <span class="at">@</span>
            <select class="input" v-model="aliasForm.domain">
              <option v-for="d in domains" :key="d.id" :value="d.domain">{{ d.domain }}</option>
            </select>
          </div>
        </label>
        <label class="field"><Eyebrow>Delivers to mailbox</Eyebrow>
          <select class="input" v-model="aliasForm.destinationUserId">
            <option v-for="u in mailboxUsers" :key="u._id" :value="u._id">{{ u.name }} · {{ u.email }}</option>
          </select>
        </label>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="aliasOpen = false">Cancel</UiButton>
        <UiButton variant="primary" :disabled="aliasBusy || !aliasForm.localPart.trim() || !aliasForm.destinationUserId" @click="submitAlias">
          {{ aliasBusy ? 'Creating…' : 'Create alias' }}
        </UiButton>
      </template>
    </Modal>

    <ConfirmDialog
      :open="!!aliasDeleteTarget"
      eyebrow="Mail · aliases"
      :title="`Delete ${aliasDeleteTarget?.address}?`"
      confirm-label="Delete alias"
      tone="danger"
      :busy="aliasDeleting"
      @close="aliasDeleteTarget = null"
      @confirm="confirmDeleteAlias"
    >
      Mail to <strong>{{ aliasDeleteTarget?.address }}</strong> will stop being delivered. The destination mailbox is unaffected.
    </ConfirmDialog>

    <!-- New list modal -->
    <Modal :open="listOpen" eyebrow="Mail · lists" title="New distribution list" size="md" @close="listOpen = false">
      <div class="form-stack">
        <label class="field"><Eyebrow>List address</Eyebrow>
          <div class="alias-row">
            <input class="input" v-model="listForm.localPart" placeholder="team" />
            <span class="at">@</span>
            <select class="input" v-model="listForm.domain">
              <option v-for="d in domains" :key="d.id" :value="d.domain">{{ d.domain }}</option>
            </select>
          </div>
        </label>
        <label class="field"><Eyebrow>Description <span class="opt">optional</span></Eyebrow><input class="input" v-model="listForm.description" placeholder="Everyone in engineering" /></label>
        <label class="field"><Eyebrow>Members <span class="opt">one email per line</span></Eyebrow>
          <textarea class="input area" v-model="listForm.recipientsText" rows="4" placeholder="anne@acme.dk&#10;mikkel@acme.dk"></textarea>
        </label>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="listOpen = false">Cancel</UiButton>
        <UiButton variant="primary" :disabled="listBusy || !listForm.localPart.trim()" @click="submitList">
          {{ listBusy ? 'Creating…' : 'Create list' }}
        </UiButton>
      </template>
    </Modal>

    <!-- Manage list members -->
    <SidePanel :open="!!openList" eyebrow="Distribution list" :title="openList?.address || ''" width="lg" @close="openList = null">
      <div v-if="openList" class="manage">
        <Eyebrow>Members <span class="opt">one email per line</span></Eyebrow>
        <textarea class="input area" v-model="manageText" rows="12" />
      </div>
      <template #footer>
        <UiButton variant="danger" @click="openList && (listDeleteTarget = openList)">
          <template #leading><UiIcon name="trash" :size="13" /></template>
          Delete list
        </UiButton>
        <div style="flex: 1" />
        <UiButton variant="secondary" @click="openList = null">Cancel</UiButton>
        <UiButton variant="primary" :disabled="manageBusy" @click="saveList">{{ manageBusy ? 'Saving…' : 'Save members' }}</UiButton>
      </template>
    </SidePanel>

    <ConfirmDialog
      :open="!!listDeleteTarget"
      eyebrow="Distribution list"
      :title="`Delete ${listDeleteTarget?.address}?`"
      confirm-label="Delete list"
      tone="danger"
      :busy="listDeleting"
      @close="listDeleteTarget = null"
      @confirm="confirmDeleteList"
    >
      Mail to this list will start bouncing immediately. Members' existing inboxes are unaffected.
    </ConfirmDialog>
  </div>
</template>

<style scoped>
.tab-wrap { padding: 16px 40px 0 40px; }
.content { padding: 20px 40px 64px 40px; }

.row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; gap: 16px; }
.lead { font-size: 13px; color: var(--text-mute); max-width: 540px; line-height: 1.5; }

.notice { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-mute); }

.tbl { width: 100%; border-collapse: collapse; }
.tbl th { text-align: left; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-mute); padding: 12px 16px; border-bottom: 1px solid var(--border); font-weight: 500; }
.tbl td { padding: 12px 16px; border-bottom: 1px solid var(--border); font-size: 13px; }
.tbl tr:last-child td { border-bottom: none; }
.tbl .right { text-align: right; white-space: nowrap; }

.lists { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.list-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.list-title { display: flex; align-items: center; gap: 8px; }
.list-name { font-family: var(--font-display); font-weight: 600; font-size: 16px; }
.list-desc { font-size: 12px; color: var(--text-mute); margin-top: 10px; }
.list-row { display: flex; gap: 8px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }

.managed { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 48px 32px; max-width: 640px; margin: 0 auto; }
.managed-title { font-family: var(--font-display); font-weight: 600; font-size: 17px; }
.managed-body { font-size: 13px; color: var(--text-mute); line-height: 1.6; max-width: 480px; }

.form-stack { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.opt { font-weight: 400; color: var(--text-mute); text-transform: none; letter-spacing: 0; }
.input { height: 36px; padding: 0 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; font-family: inherit; font-size: 13px; color: var(--text); outline: none; }
.input:focus { border-color: var(--text); }
.area { height: auto; padding: 10px 12px; font-family: var(--font-mono); line-height: 1.5; resize: vertical; }
.alias-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: center; }
.at { font-family: var(--font-mono); color: var(--text-mute); }

.manage { padding-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }
</style>
