<script setup lang="ts">
// Partner branding. Strict port of PartnerBrandingScreen
// (partner-screens.jsx lines 839-942). Three cards:
//   • Your brand · NordicMSP identity
//   • Customer defaults · what gets pushed to new customers (7 toggles)
//   • Email templates · 2-col grid of 5 templates



import type { EmailTemplate } from '~/components/partner/EmailTemplateEditor.vue'
import type { BrandIdentity } from '~/components/partner/EditIdentityModal.vue'

const toast = useToast()
const { request } = useApiFetch()

const identityOpen = ref(false)
const editing = ref<EmailTemplate | null>(null)

interface CustomerDefault {
  label: string
  detail: string
  on: boolean
}
interface PartnerBranding {
  identity: BrandIdentity
  customerDefaults: CustomerDefault[]
  emailTemplates: EmailTemplate[]
}

const { data: branding, refresh } = await useFetch<PartnerBranding>('/api/partner/branding', {
  key: 'partner-branding',
  default: () => ({ identity: {}, customerDefaults: [], emailTemplates: [] }),
})

// Source mustache literals. Constructed in JS to avoid the Vue parser eating
// nested {{ }} (see the Vue nested-mustache note).
const TAG_WORKSPACE = '{' + '{workspace.name}' + '}'
const TAG_INVOICE = '{' + '{invoice.id}' + '}'
const TAG_PLAN = '{' + '{plan.name}' + '}'

// Product defaults shown the first time a partner visits (before they save).
const DEFAULT_TOGGLES: CustomerDefault[] = [
  { label: 'Accent color',            detail: 'Apply your brand accent to customer workspaces', on: true },
  { label: 'Product name pattern',    detail: '"{Customer} Workspace"',                          on: true },
  { label: 'Custom subdomain',        detail: 'workspace.{customer-domain}',                     on: true },
  { label: 'Login screen',            detail: 'Partner co-brand + customer logo',                on: true },
  { label: 'Email templates',         detail: 'Your branded templates',                          on: true },
  { label: 'Allow customer override', detail: 'Business plans and above',                        on: true },
  { label: 'Lock typography',         detail: 'Brand-locked fonts',                              on: false },
]
const DEFAULT_TEMPLATES: EmailTemplate[] = [
  { id: 'welcome',    name: 'Customer welcome email',  subject: `Welcome to ${TAG_WORKSPACE}`,             body: '', edited: 'default' },
  { id: 'invitation', name: 'User invitation',          subject: `You’ve been invited to ${TAG_WORKSPACE}`, body: '', edited: 'default' },
  { id: 'reset',      name: 'Password reset',           subject: `Reset your ${TAG_WORKSPACE} password`,    body: '', edited: 'default' },
  { id: 'plan',       name: 'Plan change confirmation', subject: `Your plan changed to ${TAG_PLAN}`,        body: '', edited: 'default' },
  { id: 'invoice',    name: 'Invoice notification',     subject: `Invoice ${TAG_INVOICE}`,                  body: '', edited: 'default' },
]

// Editable working copies seeded from the fetched branding (falling back to the
// product defaults so the page is never blank on first visit).
const identity = ref<BrandIdentity>({})
const defaults = ref<CustomerDefault[]>([])
const templates = ref<EmailTemplate[]>([])
function clone<T>(v: T): T {
  return JSON.parse(JSON.stringify(v)) as T
}
function syncBranding() {
  const b = branding.value
  identity.value = { ...(b?.identity ?? {}) }
  defaults.value = b?.customerDefaults?.length ? clone(b.customerDefaults) : clone(DEFAULT_TOGGLES)
  templates.value = b?.emailTemplates?.length ? clone(b.emailTemplates) : clone(DEFAULT_TEMPLATES)
}
syncBranding()
watch(branding, syncBranding)

async function putBranding(): Promise<boolean> {
  try {
    await request('/api/partner/branding', {
      method: 'PUT',
      body: {
        identity: identity.value,
        customerDefaults: defaults.value,
        emailTemplates: templates.value,
      },
    })
    await Promise.all([refresh(), refreshNuxtData('partner-branding')])
    return true
  } catch (e: unknown) {
    const err = e as { data?: { message?: string }; statusMessage?: string }
    toast.bad('Save failed', err.data?.message || err.statusMessage || 'Could not save branding')
    return false
  }
}

async function toggleDefault(i: number) {
  const row = defaults.value[i]
  if (!row) return
  row.on = !row.on
  if (await putBranding()) toast.ok('Saved', 'Customer defaults updated')
}

async function saveTemplate(t: EmailTemplate) {
  templates.value = templates.value.map((x) => (x.id === t.id ? { ...t, edited: 'just now' } : x))
  editing.value = null
  if (await putBranding()) toast.ok('Template saved', t.name)
}

async function saveIdentity(payload: BrandIdentity) {
  identity.value = { ...identity.value, ...payload }
  // Close only on success so a failed save keeps the modal open (with its toast).
  if (await putBranding()) {
    identityOpen.value = false
    toast.ok('Saved', 'Brand identity updated')
  }
}
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Whitelabel"
      title="Partner branding"
      subtitle="Your own brand identity, plus the defaults pushed to every customer you provision."
    />

    <div class="content">
      <!-- Your brand · identity card -->
      <Card>
        <div class="card-head">
          <div>
            <Eyebrow>Your brand</Eyebrow>
            <div class="card-title">NordicMSP identity</div>
            <p class="sub">Shown in the partner console and on emails sent by your team.</p>
          </div>
          <UiButton size="sm" variant="ghost" @click="identityOpen = true">Edit</UiButton>
        </div>
        <div class="id-grid">
          <dl class="def">
            <div><dt>Display name</dt><dd>{{ identity.displayName || '—' }}</dd></div>
            <div><dt>Logo</dt><dd>{{ identity.logoUrl || 'not set' }}</dd></div>
            <div><dt>Mark</dt><dd>{{ identity.markUrl || 'not set' }}</dd></div>
            <div>
              <dt>Primary color</dt>
              <dd>
                <div class="color-row">
                  <div class="color-swatch" :style="{ background: identity.primaryColor || '#3F6BFF' }" />
                  <Mono>{{ identity.primaryColor || '#3F6BFF' }}</Mono>
                </div>
              </dd>
            </div>
          </dl>
          <dl class="def">
            <div><dt>Support email</dt><dd>{{ identity.supportEmail || '—' }}</dd></div>
            <div><dt>Support phone</dt><dd>{{ identity.supportPhone || '—' }}</dd></div>
            <div><dt>Website</dt><dd>{{ identity.website || '—' }}</dd></div>
            <div><dt>Reply-to</dt><dd>{{ identity.replyTo || '—' }}</dd></div>
          </dl>
        </div>
      </Card>

      <!-- Customer defaults · toggle list -->
      <Card>
        <div class="card-head">
          <div>
            <Eyebrow>Customer defaults</Eyebrow>
            <div class="card-title">What gets pushed to new customers</div>
            <p class="sub">Applied at provisioning. Customers can override per their tier entitlements.</p>
          </div>
        </div>
        <div class="defaults-list">
          <div
            v-for="(row, i) in defaults"
            :key="row.label"
            class="def-row"
            :class="{ last: i === defaults.length - 1 }"
          >
            <div class="dr-meta">
              <div class="dr-label">{{ row.label }}</div>
              <div class="dr-detail">{{ row.detail }}</div>
            </div>
            <button class="switch" :class="{ on: row.on }" @click="toggleDefault(i)">
              <span class="thumb" />
            </button>
          </div>
        </div>
      </Card>

      <!-- Email templates · 2-col grid -->
      <Card>
        <Eyebrow>Templates</Eyebrow>
        <div class="card-title">Email templates · NordicMSP defaults</div>
        <div class="tpl-grid">
          <button
            v-for="t in templates"
            :key="t.id"
            class="tpl-row"
            @click="editing = t"
          >
            <UiIcon name="mail" :size="14" />
            <div class="tpl-meta">
              <div class="tpl-top">
                <span class="tpl-name">{{ t.name }}</span>
                <Badge :tone="t.edited === 'default' ? 'neutral' : 'info'">{{ t.edited === 'default' ? 'default' : 'edited' }}</Badge>
              </div>
              <Mono dim>edited {{ t.edited }}</Mono>
            </div>
            <UiIcon name="chevRight" :size="14" />
          </button>
        </div>
      </Card>
    </div>

    <PartnerEditIdentityModal
      :open="identityOpen"
      :identity="identity"
      @close="identityOpen = false"
      @save="saveIdentity"
    />

    <PartnerEmailTemplateEditor
      :template="editing"
      :brand-color="identity.primaryColor || '#3F6BFF'"
      :brand-name="identity.displayName || 'Your brand'"
      @close="editing = null"
      @save="saveTemplate"
    />
  </div>
</template>

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

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
}
.card-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17px;
  margin-top: 4px;
}
.sub { font-size: 13px; color: var(--text-mute); margin: 6px 0 0; max-width: 580px; line-height: 1.5; }

/* Identity DefList grid */
.id-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.def { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; }
.def div { display: grid; grid-template-columns: 140px 1fr; gap: 12px; font-size: 13px; align-items: center; }
.def dt { color: var(--text-mute); font-family: var(--font-mono); font-size: 11px; }
.def dd { margin: 0; }
.color-row { display: flex; align-items: center; gap: 8px; }
.color-swatch { width: 14px; height: 14px; border-radius: 3px; }

/* Defaults toggle list */
.defaults-list { display: flex; flex-direction: column; }
.def-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.def-row.last { border-bottom: none; }
.dr-meta { flex: 1; min-width: 0; }
.dr-label { font-size: 13px; font-weight: 500; }
.dr-detail { font-size: 12px; color: var(--text-mute); margin-top: 2px; }

.switch {
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: var(--border);
  border: none;
  padding: 2px;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  transition: background 150ms;
  flex-shrink: 0;
}
.switch.on { background: var(--text); }
.thumb {
  width: 16px;
  height: 16px;
  border-radius: 999px;
  background: var(--bg);
  transition: transform 150ms;
}
.switch.on .thumb { transform: translateX(16px); }

/* Templates grid */
.tpl-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-top: 12px;
}
.tpl-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  text-align: left;
}
.tpl-row:hover { background: var(--row-hover); }
.tpl-row :deep(svg) { color: var(--text-mute); flex-shrink: 0; }
.tpl-meta { flex: 1; min-width: 0; }
.tpl-top { display: flex; align-items: center; gap: 8px; }
.tpl-name { font-weight: 500; }
</style>
