<script setup lang="ts">
// Customer whitelabel branding. Real data: product name + accent colour (on the
// Tenant doc) and email-template overrides (TenantBranding), saved together via
// PUT /api/tenants/:slug/branding. No backend yet for logo upload or custom-
// domain verification, so those show honest "coming soon" states.
//
// Edit model: name/colour + the open template editor mutate LOCAL state; the
// header "Save changes" persists everything in one PUT. The per-template
// "Apply" just commits that template into local overrides.

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

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

const DEFAULT_COLOR = '#D4FF3A'
const colorPalette = ['#D4FF3A', '#3F6BFF', '#FF6B4A', '#5B8C5A', '#9B59B6']

const { data: branding } = await useFetch<TenantBrandingView>(
  () => `/api/tenants/${slug.value}/branding`,
  { key: 'admin-branding', default: () => ({ name: '', emailTemplates: [] }), immediate: !!slug.value, watch: [slug] },
)

// Local editable state, seeded from the fetched branding.
const name = ref('')
const color = ref(DEFAULT_COLOR)
const overrides = reactive<Record<string, { subject: string; body: string }>>({})
function seed() {
  const b = branding.value
  name.value = b?.name ?? ''
  color.value = b?.brandColor || DEFAULT_COLOR
  for (const k of Object.keys(overrides)) delete overrides[k]
  for (const t of b?.emailTemplates ?? []) overrides[t.key] = { subject: t.subject, body: t.body }
}
seed()
watch(branding, seed)

const primaryDomain = computed(() => branding.value?.primaryDomain ?? '')

// Auto-contrast foreground for surfaces painted in the accent colour, so the
// preview stays legible whether the accent is bright or dark.
const accentFg = computed(() => readableOn(color.value))
const accentBtnText = computed(() => readableOn(accentFg.value))

// Canonical template defaults. Overrides (saved per tenant) win over these.
const TEMPLATES = [
  { id: 'invitation', name: 'User invitation',     subject: 'You’ve been invited to {{workspace.name}}',   desc: 'sent when an admin invites a new user' },
  { id: 'reset',      name: 'Password reset',      subject: 'Reset your {{workspace.name}} password',      desc: 'sent on forgot-password requests' },
  { id: 'digest',     name: 'Notification digest', subject: 'Your weekly summary from {{workspace.name}}', desc: 'sent weekly to users opted-in for digests' },
  { id: 'trial',      name: 'Trial expiring',      subject: 'Your trial ends in {{trial.days_left}} days', desc: 'sent 7 / 3 / 1 days before trial expiry' },
] as const

const TEMPLATE_BODIES: Record<string, string> = {
  invitation: `Hi {{user.first_name}},

{{inviter.name}} has invited you to join {{workspace.name}}.

Click below to set up your account — the link expires in 7 days.

→ {{invite.url}}

If you have any questions, reply to this email and we'll help out.

— The {{workspace.name}} team`,
  reset: `Hi {{user.first_name}},

Someone (hopefully you) asked to reset your {{workspace.name}} password.

Click the link below within the next 60 minutes to choose a new one:

→ {{reset.url}}

If you didn't request this, you can safely ignore this email.

— {{workspace.name}} security`,
  digest: `Hi {{user.first_name}},

Here's what happened in {{workspace.name}} this week:

· {{stats.messages}} new messages across your channels
· {{stats.files}} files shared
· {{stats.meetings}} meetings recorded

→ Open dashboard: {{workspace.url}}

Manage how often you receive these from your profile.`,
  trial: `Hi {{user.first_name}},

Your {{workspace.name}} trial ends in {{trial.days_left}} days.

You've added {{stats.users}} users and uploaded {{stats.gb}} GB of files. To keep everything running smoothly, upgrade to Business or Enterprise.

→ Choose a plan: {{billing.url}}

— {{workspace.name}}`,
}

const TEMPLATE_MERGE_TAGS: Record<string, string[]> = {
  invitation: ['user.first_name', 'user.email', 'inviter.name', 'workspace.name', 'invite.url', 'invite.expires_at'],
  reset:      ['user.first_name', 'workspace.name', 'reset.url', 'reset.expires_at', 'security.ip'],
  digest:     ['user.first_name', 'workspace.name', 'workspace.url', 'stats.messages', 'stats.files', 'stats.meetings'],
  trial:      ['user.first_name', 'workspace.name', 'trial.days_left', 'stats.users', 'stats.gb', 'billing.url'],
}

function isEdited(id: string): boolean {
  return !!overrides[id]
}

// ── Template editor (side panel) ─────────────────────────────────────────
const editTemplate = ref<typeof TEMPLATES[number] | null>(null)
const subject = ref('')
const body = ref('')
const testSent = ref(false)

function openTemplate(t: typeof TEMPLATES[number]) {
  editTemplate.value = t
  subject.value = overrides[t.id]?.subject ?? t.subject
  body.value = overrides[t.id]?.body ?? (TEMPLATE_BODIES[t.id] || '')
  testSent.value = false
}

// Wrap a merge-tag name in mustaches via JS so the template never nests
// `{{ ... }}` inside `{{ ... }}` (Vue's parser scans positionally and breaks).
function wrapTag(tag: string) {
  return '{' + '{' + tag + '}' + '}'
}
function insertTag(tag: string) {
  body.value += wrapTag(tag)
}

// Commit the open template into local overrides (header Save persists).
function applyTemplate() {
  if (!editTemplate.value) return
  overrides[editTemplate.value.id] = { subject: subject.value, body: body.value }
  editTemplate.value = null
}

// Drop the override → revert to the canonical default (persisted on Save).
function resetTemplate() {
  if (!editTemplate.value) return
  delete overrides[editTemplate.value.id]
  subject.value = editTemplate.value.subject
  body.value = TEMPLATE_BODIES[editTemplate.value.id] || ''
  toast.info('Reverted to default', 'Save changes to apply')
}

function sendTest() {
  testSent.value = true
  setTimeout(() => (testSent.value = false), 2500)
}

const renderedSubject = computed(() =>
  subject.value
    .replace(/\{\{workspace\.name\}\}/g, name.value)
    .replace(/\{\{user\.first_name\}\}/g, 'Anne')
    .replace(/\{\{trial\.days_left\}\}/g, '3'),
)
const renderedBody = computed(() =>
  body.value
    .replace(/\{\{workspace\.name\}\}/g, name.value)
    .replace(/\{\{workspace\.url\}\}/g, primaryDomain.value || 'your-workspace')
    .replace(/\{\{user\.first_name\}\}/g, 'Anne')
    .replace(/\{\{user\.email\}\}/g, 'anne@example.com')
    .replace(/\{\{inviter\.name\}\}/g, 'Mikkel Nørgaard')
    .replace(/\{\{invite\.url\}\}/g, `${primaryDomain.value || 'your-workspace'}/accept/x9k2a`)
    .replace(/\{\{reset\.url\}\}/g, `${primaryDomain.value || 'your-workspace'}/reset/p2b7c`)
    .replace(/\{\{billing\.url\}\}/g, `${primaryDomain.value || 'your-workspace'}/billing`)
    .replace(/\{\{trial\.days_left\}\}/g, '3')
    .replace(/\{\{stats\.messages\}\}/g, '1.840')
    .replace(/\{\{stats\.files\}\}/g, '24')
    .replace(/\{\{stats\.meetings\}\}/g, '6')
    .replace(/\{\{stats\.users\}\}/g, '8')
    .replace(/\{\{stats\.gb\}\}/g, '14'),
)

// ── Save ─────────────────────────────────────────────────────────────────
const saving = ref(false)
async function save() {
  if (!slug.value) return
  saving.value = true
  try {
    const payload = {
      name: name.value,
      brandColor: color.value,
      emailTemplates: Object.entries(overrides).map(([key, v]) => ({ key, subject: v.subject, body: v.body })),
    }
    branding.value = await request<TenantBrandingView>(`/api/tenants/${slug.value}/branding`, {
      method: 'PUT',
      body: payload,
    })
    await fetchMe(true) // name lives on the tenant → refresh dashboard/sidebar identity
    toast.ok('Branding saved')
  } catch (e: unknown) {
    const msg = (e as { data?: { message?: string | string[] } })?.data?.message
    toast.bad('Could not save branding', Array.isArray(msg) ? msg.join(', ') : msg)
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Whitelabel"
      title="Branding"
      subtitle="Give your workspace its own name, accent colour, and email copy."
    >
      <template #actions>
        <UiButton variant="primary" :disabled="saving || !slug" @click="save">
          <template #leading><UiIcon name="check" :size="14" /></template>
          {{ saving ? 'Saving…' : 'Save changes' }}
        </UiButton>
      </template>
    </PageHeader>

    <div class="content">
      <!-- Controls -->
      <div class="controls">
        <Card>
          <div class="card-head"><Eyebrow>Identity</Eyebrow><div class="card-title">Product identity</div></div>
          <label class="field"><Eyebrow>Product name (shown to users)</Eyebrow><input class="input" v-model="name" /></label>
          <label class="field"><Eyebrow>Custom domain</Eyebrow>
            <div v-if="primaryDomain" class="input-row">
              <input :value="primaryDomain" readonly />
            </div>
            <div v-else class="soon-inline">
              <Mono dim>Custom domains coming soon</Mono>
            </div>
          </label>
        </Card>

        <Card>
          <div class="card-head">
            <Eyebrow>Color</Eyebrow>
            <div class="card-title">Primary accent</div>
            <div class="card-sub">Propagates to buttons, links, focus rings, and active states.</div>
          </div>
          <div class="swatches">
            <button v-for="c in colorPalette" :key="c" :style="{ background: c, borderColor: color === c ? 'var(--text)' : 'var(--border)', borderWidth: color === c ? '2px' : '1px' }" @click="color = c" />
          </div>
          <div class="input-row">
            <input v-model="color" />
            <div class="color-preview" :style="{ background: color }" />
          </div>
        </Card>

        <Card>
          <div class="card-head"><Eyebrow>Assets</Eyebrow><div class="card-title">Logo upload</div></div>
          <div class="soon-box">
            <UiIcon name="upload" :size="16" stroke="var(--text-mute)" />
            <div>Logo, square mark and favicon upload is coming soon. For now your accent colour and product name drive the workspace look.</div>
          </div>
        </Card>

        <Card>
          <div class="card-head"><Eyebrow>Templates</Eyebrow><div class="card-title">Email templates</div></div>
          <div class="templates">
            <button v-for="t in TEMPLATES" :key="t.id" class="tmpl-row" @click="openTemplate(t)">
              <div class="tmpl-meta">
                <div class="tmpl-name-row">
                  <span class="tmpl-name">{{ t.name }}</span>
                  <Badge :tone="isEdited(t.id) ? 'info' : 'neutral'">{{ isEdited(t.id) ? 'edited' : 'default' }}</Badge>
                </div>
                <Mono dim>{{ t.desc }}</Mono>
              </div>
              <UiIcon name="chevRight" :size="14" stroke="var(--text-mute)" />
            </button>
          </div>
        </Card>
      </div>

      <!-- Preview -->
      <div class="preview-col">
        <div class="preview-head">
          <Eyebrow>Live preview</Eyebrow>
          <Mono dim>{{ primaryDomain || slug }}</Mono>
        </div>
        <div class="preview-frame">
          <div class="frame-topbar">
            <div class="frame-mark" :style="{ background: color, color: accentFg }">{{ name[0]?.toLowerCase() || 'a' }}</div>
            <div class="frame-brand">{{ name.toLowerCase() }}</div>
            <div class="frame-spacer" />
            <div class="frame-user">{{ primaryDomain ? `you@${primaryDomain}` : 'your team' }}</div>
          </div>
          <div class="frame-hero">
            <div class="frame-eyebrow">Dashboard</div>
            <div class="frame-title">Good morning.</div>
            <div class="frame-tiles">
              <div v-for="n in ['Mail', 'Drev', 'Møder', 'Chat']" :key="n" class="frame-tile">
                <div class="frame-tile-icon">{{ n[0] }}</div>
                <div class="frame-tile-name">{{ n }}</div>
              </div>
            </div>
            <div class="frame-cta" :style="{ background: color }">
              <div>
                <div class="frame-cta-title" :style="{ color: accentFg }">Welcome to {{ name || 'your workspace' }}.</div>
                <div class="frame-cta-sub" :style="{ color: accentFg, opacity: 0.75 }">Your team's workspace is ready.</div>
              </div>
              <button class="frame-cta-btn" :style="{ background: accentFg, color: accentBtnText }">Get started</button>
            </div>
          </div>
          <div class="frame-foot">
            <span>powered by dezky</span>
            <span>v1.0 · light</span>
          </div>
        </div>
      </div>
    </div>

    <!-- Edit email template side panel -->
    <SidePanel :open="!!editTemplate" :eyebrow="'Email template'" :title="editTemplate?.name || ''" width="lg" @close="editTemplate = null">
      <div v-if="editTemplate" class="tmpl-edit">
        <div class="tmpl-col">
          <label class="field"><Eyebrow>Subject</Eyebrow><input class="input" v-model="subject" /></label>
          <div>
            <Eyebrow>Body</Eyebrow>
            <textarea v-model="body" class="body-area" />
          </div>
          <div>
            <Eyebrow>Merge tags · click to insert</Eyebrow>
            <div class="merge-tags">
              <button v-for="tag in (TEMPLATE_MERGE_TAGS[editTemplate.id] || [])" :key="tag" @click="insertTag(tag)">{{ wrapTag(tag) }}</button>
            </div>
          </div>
        </div>
        <div class="tmpl-prev">
          <Eyebrow>Preview</Eyebrow>
          <div class="email-frame">
            <div class="email-head">
              <div class="from-row">
                <div class="from-mark" :style="{ background: '#0A0A0A', color }">{{ name[0]?.toLowerCase() || 'a' }}</div>
                <Mono dim>From: {{ (name || 'workspace').toLowerCase().replace(/\s+/g, '-') }}</Mono>
              </div>
              <div class="email-subj">{{ renderedSubject }}</div>
            </div>
            <div class="email-body">{{ renderedBody }}</div>
            <div class="email-foot" :style="{ background: color, color: accentFg }">{{ name || 'Your workspace' }}{{ primaryDomain ? ` · ${primaryDomain}` : '' }}</div>
          </div>
          <Mono dim style="text-align: center; display: block;">preview substitutes sample data · real send uses recipient's data</Mono>
        </div>
      </div>
      <template #footer>
        <UiButton variant="ghost" @click="resetTemplate">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Reset to default
        </UiButton>
        <div style="flex: 1" />
        <UiButton variant="secondary" @click="sendTest">
          <template #leading><UiIcon name="mail" :size="13" /></template>
          {{ testSent ? 'Test queued ✓' : 'Send test to me' }}
        </UiButton>
        <UiButton variant="primary" @click="applyTemplate">
          <template #leading><UiIcon name="check" :size="13" /></template>
          Apply
        </UiButton>
      </template>
    </SidePanel>
  </div>
</template>

<style scoped>
.content { padding: 24px 40px 64px 40px; display: grid; grid-template-columns: 420px 1fr; gap: 24px; }
.controls { display: flex; flex-direction: column; gap: 16px; }

.card-head { margin-bottom: 14px; }
.card-title { font-family: var(--font-display); font-weight: 600; font-size: 18px; letter-spacing: -0.01em; margin-top: 4px; }
.card-sub { font-size: 13px; color: var(--text-mute); margin-top: 4px; }

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field:last-child { margin-bottom: 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); }
.input-row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.input-row input { flex: 1; border: none; outline: none; background: transparent; font-family: inherit; font-size: 13px; color: var(--text); }
.color-preview { width: 36px; height: 36px; border-radius: 6px; border: 1px solid var(--border); flex-shrink: 0; }
.soon-inline { padding: 8px 0; }

.soon-box {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 14px;
  background: var(--bg);
  border: 1px dashed var(--border-hi, var(--border));
  border-radius: 6px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.5;
}

.swatches { display: flex; gap: 10px; margin-bottom: 14px; }
.swatches button { width: 38px; height: 38px; border-radius: 6px; cursor: pointer; }

.templates { display: flex; flex-direction: column; }
.tmpl-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); background: transparent; border-left: none; border-right: none; border-top: none; text-align: left; color: var(--text); font-family: inherit; font-size: 13px; cursor: pointer; }
.tmpl-row:last-child { border-bottom: none; }
.tmpl-meta { flex: 1; min-width: 0; }
.tmpl-name-row { display: flex; align-items: center; gap: 8px; }
.tmpl-name { font-weight: 500; }

.preview-col { min-width: 0; }
.preview-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.preview-frame {
  background: #FAFAF7;
  color: #0A0A0A;
  border-radius: 10px;
  border: 1px solid var(--border);
  overflow: hidden;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
  font-family: 'Inter', sans-serif;
}
.frame-topbar {
  height: 52px;
  background: #0A0A0A;
  color: #F4F3EE;
  display: flex;
  align-items: center;
  padding: 0 20px;
  gap: 16px;
}
.frame-mark {
  width: 24px;
  height: 24px;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 13px;
  color: #0A0A0A;
}
.frame-brand { font-family: var(--font-mono); font-size: 13px; font-weight: 600; }
.frame-spacer { flex: 1; }
.frame-user { font-size: 11px; font-family: var(--font-mono); opacity: 0.6; }
.frame-hero { padding: 36px 32px 24px 32px; }
.frame-eyebrow { font-family: var(--font-mono); font-size: 10px; color: #5A5A55; letter-spacing: 0.12em; text-transform: uppercase; }
.frame-title { font-family: var(--font-display); font-size: 28px; font-weight: 600; letter-spacing: -0.02em; margin-top: 8px; }
.frame-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 20px; }
.frame-tile { background: #fff; border: 1px solid #E6E4DC; border-radius: 6px; padding: 14px; }
.frame-tile-icon {
  width: 24px;
  height: 24px;
  border-radius: 5px;
  background: #0A0A0A;
  color: #F4F3EE;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 11px;
}
.frame-tile-name { font-family: var(--font-display); font-weight: 600; font-size: 14px; margin-top: 12px; }
.frame-cta { margin-top: 24px; padding: 18px 20px; border-radius: 6px; display: flex; align-items: center; justify-content: space-between; }
.frame-cta-title { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: #0A0A0A; }
.frame-cta-sub { font-size: 12px; color: rgba(10, 10, 10, 0.7); margin-top: 4px; }
.frame-cta-btn { height: 32px; padding: 0 14px; border-radius: 5px; border: none; background: #0A0A0A; color: #F4F3EE; font-weight: 600; font-size: 12px; cursor: pointer; }
.frame-foot { padding: 12px 32px; border-top: 1px solid #E6E4DC; background: #F4F3EE; font-size: 11px; color: #5A5A55; font-family: var(--font-mono); display: flex; justify-content: space-between; }

/* Email template editor */
.tmpl-edit { display: grid; grid-template-columns: 1fr 1fr; min-height: 0; height: 100%; }
.tmpl-col { padding: 24px; border-right: 1px solid var(--border); display: flex; flex-direction: column; gap: 14px; }
.tmpl-prev { padding: 24px; background: var(--bg); display: flex; flex-direction: column; gap: 12px; }
.body-area {
  width: 100%;
  min-height: 320px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
  font-family: var(--font-mono);
  line-height: 1.6;
  resize: vertical;
  outline: none;
  box-sizing: border-box;
}
.merge-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.merge-tags button {
  padding: 4px 8px;
  border-radius: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text);
  cursor: pointer;
}
.email-frame {
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #E6E4DC;
  color: #0A0A0A;
  font-family: 'Inter', sans-serif;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.email-head { padding: 16px 20px; border-bottom: 1px solid #E6E4DC; background: #FAFAF7; }
.from-row { display: flex; align-items: center; gap: 8px; }
.from-mark {
  width: 22px;
  height: 22px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
}
.email-subj { font-family: var(--font-display); font-weight: 600; font-size: 16px; margin-top: 10px; color: #0A0A0A; }
.email-body { padding: 20px; font-size: 13px; line-height: 1.65; color: #3A3A35; white-space: pre-wrap; flex: 1; overflow-y: auto; }
.email-foot { padding: 14px 20px; border-top: 1px solid #E6E4DC; color: #0A0A0A; font-size: 11px; font-family: var(--font-mono); text-align: center; }
</style>
