'use client';

/**
 * Sales send-from config card (Phase 7 §5.9).
 *
 * Lives on /[portSlug]/admin/email below the existing noreply transport
 * card. Lets per-port admins configure the SMTP/IMAP creds + body templates
 * that the document-sends flow uses.
 *
 * §14.10 enforcement: passwords are write-only. The GET endpoint never
 * returns the decrypted value — only a `*PassIsSet` boolean. Empty
 * password input means "leave unchanged"; explicit `null` sent over the
 * wire means "clear".
 */
import { useEffect, useState } from 'react';
import { Loader2 } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { apiFetch } from '@/lib/api/client';

interface SalesConfigResponse {
  data: {
    email: {
      fromAddress: string;
      smtpHost: string | null;
      smtpPort: number;
      smtpSecure: boolean;
      smtpUser: string | null;
      authMethod: string;
      smtpPassIsSet: boolean;
      isUsable: boolean;
    };
    imap: {
      imapHost: string | null;
      imapPort: number;
      imapUser: string | null;
      imapPassIsSet: boolean;
      isUsable: boolean;
    };
    content: {
      noreplyFromAddress: string;
      templateBerthPdfBody: string;
      templateBrochureBody: string;
      brochureMaxUploadMb: number;
      emailAttachThresholdMb: number;
    };
  };
}

interface FormState {
  fromAddress: string;
  smtpHost: string;
  smtpPort: number | '';
  smtpSecure: boolean;
  smtpUser: string;
  smtpPass: string; // empty = unchanged
  imapHost: string;
  imapPort: number | '';
  imapUser: string;
  imapPass: string;
  noreplyFromAddress: string;
  templateBerthPdfBody: string;
  templateBrochureBody: string;
  brochureMaxUploadMb: number | '';
  emailAttachThresholdMb: number | '';
}

const EMPTY_FORM: FormState = {
  fromAddress: '',
  smtpHost: '',
  smtpPort: 587,
  smtpSecure: false,
  smtpUser: '',
  smtpPass: '',
  imapHost: '',
  imapPort: 993,
  imapUser: '',
  imapPass: '',
  noreplyFromAddress: '',
  templateBerthPdfBody: '',
  templateBrochureBody: '',
  brochureMaxUploadMb: 50,
  emailAttachThresholdMb: 15,
};

export function SalesEmailConfigCard() {
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [smtpPassSet, setSmtpPassSet] = useState(false);
  const [imapPassSet, setImapPassSet] = useState(false);
  const [form, setForm] = useState<FormState>(EMPTY_FORM);

  async function refresh() {
    setLoading(true);
    try {
      const res: SalesConfigResponse = await apiFetch('/api/v1/admin/email/sales-config');
      setSmtpPassSet(res.data.email.smtpPassIsSet);
      setImapPassSet(res.data.imap.imapPassIsSet);
      setForm({
        fromAddress: res.data.email.fromAddress,
        smtpHost: res.data.email.smtpHost ?? '',
        smtpPort: res.data.email.smtpPort,
        smtpSecure: res.data.email.smtpSecure,
        smtpUser: res.data.email.smtpUser ?? '',
        smtpPass: '',
        imapHost: res.data.imap.imapHost ?? '',
        imapPort: res.data.imap.imapPort,
        imapUser: res.data.imap.imapUser ?? '',
        imapPass: '',
        noreplyFromAddress: res.data.content.noreplyFromAddress,
        templateBerthPdfBody: res.data.content.templateBerthPdfBody,
        templateBrochureBody: res.data.content.templateBrochureBody,
        brochureMaxUploadMb: res.data.content.brochureMaxUploadMb,
        emailAttachThresholdMb: res.data.content.emailAttachThresholdMb,
      });
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void refresh();
  }, []);

  function update<K extends keyof FormState>(key: K, value: FormState[K]) {
    setForm((prev) => ({ ...prev, [key]: value }));
  }

  async function handleSave() {
    setSaving(true);
    try {
      const payload: Record<string, unknown> = {
        fromAddress: form.fromAddress || null,
        smtpHost: form.smtpHost || null,
        smtpPort: typeof form.smtpPort === 'number' ? form.smtpPort : null,
        smtpSecure: form.smtpSecure,
        smtpUser: form.smtpUser || null,
        imapHost: form.imapHost || null,
        imapPort: typeof form.imapPort === 'number' ? form.imapPort : null,
        imapUser: form.imapUser || null,
        noreplyFromAddress: form.noreplyFromAddress || null,
        templateBerthPdfBody: form.templateBerthPdfBody,
        templateBrochureBody: form.templateBrochureBody,
        brochureMaxUploadMb:
          typeof form.brochureMaxUploadMb === 'number' ? form.brochureMaxUploadMb : null,
        emailAttachThresholdMb:
          typeof form.emailAttachThresholdMb === 'number' ? form.emailAttachThresholdMb : null,
      };
      // Only send password fields when the user actually typed something.
      if (form.smtpPass !== '') payload.smtpPass = form.smtpPass;
      if (form.imapPass !== '') payload.imapPass = form.imapPass;

      await apiFetch('/api/v1/admin/email/sales-config', { method: 'PATCH', body: payload });
      toast.success('Sales email settings saved');
      await refresh();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Save failed');
    } finally {
      setSaving(false);
    }
  }

  if (loading) {
    return (
      <Card>
        <CardContent className="flex items-center gap-2 py-6 text-sm text-muted-foreground">
          <Loader2 className="h-4 w-4 animate-spin" /> Loading sales email config…
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader>
          <CardTitle>Sales send-from account</CardTitle>
          <CardDescription>
            SMTP credentials for human-touch outbound (brochures + per-berth PDFs). IMAP creds
            enable the bounce monitor — leave blank to disable bounce-rejection banners. Passwords
            are encrypted at rest and never returned by the API.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-3 md:grid-cols-2">
            <Field label="From address" id="sef-from">
              <Input
                id="sef-from"
                type="email"
                value={form.fromAddress}
                onChange={(e) => update('fromAddress', e.target.value)}
                placeholder="sales@portnimara.com"
              />
            </Field>
            <Field label="SMTP host" id="sef-smtp-host">
              <Input
                id="sef-smtp-host"
                value={form.smtpHost}
                onChange={(e) => update('smtpHost', e.target.value)}
                placeholder="smtp.gmail.com"
              />
            </Field>
            <Field label="SMTP port" id="sef-smtp-port">
              <Input
                id="sef-smtp-port"
                type="number"
                value={form.smtpPort}
                onChange={(e) =>
                  update('smtpPort', e.target.value === '' ? '' : Number(e.target.value))
                }
              />
            </Field>
            <div className="flex items-end justify-between gap-2">
              <Label htmlFor="sef-smtp-secure" className="text-sm">
                SSL (true=465, false=STARTTLS on 587)
              </Label>
              <Switch
                id="sef-smtp-secure"
                checked={form.smtpSecure}
                onCheckedChange={(v) => update('smtpSecure', v)}
              />
            </div>
            <Field label="SMTP username" id="sef-smtp-user">
              <Input
                id="sef-smtp-user"
                value={form.smtpUser}
                onChange={(e) => update('smtpUser', e.target.value)}
              />
            </Field>
            <Field
              label={`SMTP password ${smtpPassSet ? '(stored — leave blank to keep)' : ''}`}
              id="sef-smtp-pass"
            >
              <Input
                id="sef-smtp-pass"
                type="password"
                value={form.smtpPass}
                onChange={(e) => update('smtpPass', e.target.value)}
                placeholder={smtpPassSet ? '••••••••' : 'app password'}
              />
            </Field>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Bounce monitor (IMAP)</CardTitle>
          <CardDescription>
            Required only for the async-bounce banner (§14.9). Same provider account as SMTP in most
            setups.
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-3 md:grid-cols-2">
          <Field label="IMAP host" id="sef-imap-host">
            <Input
              id="sef-imap-host"
              value={form.imapHost}
              onChange={(e) => update('imapHost', e.target.value)}
              placeholder="imap.gmail.com"
            />
          </Field>
          <Field label="IMAP port" id="sef-imap-port">
            <Input
              id="sef-imap-port"
              type="number"
              value={form.imapPort}
              onChange={(e) =>
                update('imapPort', e.target.value === '' ? '' : Number(e.target.value))
              }
            />
          </Field>
          <Field label="IMAP username" id="sef-imap-user">
            <Input
              id="sef-imap-user"
              value={form.imapUser}
              onChange={(e) => update('imapUser', e.target.value)}
            />
          </Field>
          <Field
            label={`IMAP password ${imapPassSet ? '(stored — leave blank to keep)' : ''}`}
            id="sef-imap-pass"
          >
            <Input
              id="sef-imap-pass"
              type="password"
              value={form.imapPass}
              onChange={(e) => update('imapPass', e.target.value)}
              placeholder={imapPassSet ? '••••••••' : 'app password'}
            />
          </Field>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Body templates</CardTitle>
          <CardDescription>
            Default markdown bodies used when a rep doesn&rsquo;t write a custom one. Tokens like{' '}
            <code>{'{{client.fullName}}'}</code> are expanded server-side.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <Field label="Berth PDF body" id="sef-tmpl-berth">
            <Textarea
              id="sef-tmpl-berth"
              rows={6}
              value={form.templateBerthPdfBody}
              onChange={(e) => update('templateBerthPdfBody', e.target.value)}
              className="font-mono text-sm"
            />
          </Field>
          <Field label="Brochure body" id="sef-tmpl-broc">
            <Textarea
              id="sef-tmpl-broc"
              rows={6}
              value={form.templateBrochureBody}
              onChange={(e) => update('templateBrochureBody', e.target.value)}
              className="font-mono text-sm"
            />
          </Field>
          <div className="grid gap-3 md:grid-cols-2">
            <Field label="Brochure max upload (MB)" id="sef-broc-max">
              <Input
                id="sef-broc-max"
                type="number"
                value={form.brochureMaxUploadMb}
                onChange={(e) =>
                  update('brochureMaxUploadMb', e.target.value === '' ? '' : Number(e.target.value))
                }
              />
            </Field>
            <Field label="Attach-vs-link threshold (MB)" id="sef-attach">
              <Input
                id="sef-attach"
                type="number"
                value={form.emailAttachThresholdMb}
                onChange={(e) =>
                  update(
                    'emailAttachThresholdMb',
                    e.target.value === '' ? '' : Number(e.target.value),
                  )
                }
              />
            </Field>
          </div>
          <Field label="Noreply from address" id="sef-noreply">
            <Input
              id="sef-noreply"
              type="email"
              value={form.noreplyFromAddress}
              onChange={(e) => update('noreplyFromAddress', e.target.value)}
            />
          </Field>
        </CardContent>
      </Card>

      <div className="flex justify-end">
        <Button onClick={handleSave} disabled={saving}>
          {saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
          Save sales email settings
        </Button>
      </div>
    </div>
  );
}

function Field({ label, id, children }: { label: string; id: string; children: React.ReactNode }) {
  return (
    <div className="space-y-1">
      <Label htmlFor={id}>{label}</Label>
      {children}
    </div>
  );
}
