'use client';

import { useEffect, useState } from 'react';
import { useAuth } from '@/lib/auth-context';
import { adminApiFetch } from '@/lib/api';
import { useToast } from '@/lib/toast';
import { fillTemplate } from '@/lib/template-placeholders';
import AttachmentPicker, { Attachment } from '@/components/AttachmentPicker';
import AiPolishButton from '@/components/AiPolishButton';
import { useLiveRefresh } from '@/lib/realtime';
import { TableSkeleton } from '@/components/Skeletons';

type Template = { id: number; name: string; category: string; subject: string; body: string; isBuiltIn: boolean };
type ClientLookup = { id: number; name: string; company: string | null; phone: string; email: string | null };
type SentRow = {
  id: number; toEmail: string; subject: string; status: string; errorMessage: string | null;
  createdAt: string; fromIdentity?: string | null; client: { name: string } | null; sentBy: { name: string } | null;
};
type Mailbox = { identity: string; configured: boolean; ok: boolean; address: string; error?: string };

const emptyForm = { toEmail: '', ccEmail: '', subject: '', body: '' };

export default function EmailComposerPage() {
  const { accessToken, appSecretProof } = useAuth();
  const { show } = useToast();
  const [templates, setTemplates] = useState<Template[]>([]);
  const [clients, setClients] = useState<ClientLookup[]>([]);
  const [sent, setSent] = useState<SentRow[]>([]);
  const [mailboxes, setMailboxes] = useState<Mailbox[]>([]);
  const [testing, setTesting] = useState(false);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [form, setForm] = useState(emptyForm);
  const [selectedClientId, setSelectedClientId] = useState('');
  const [attachments, setAttachments] = useState<Attachment[]>([]);
  const [sending, setSending] = useState(false);

  async function load() {
    if (!accessToken || !appSecretProof) return;
    setLoading(true);
    try {
      const [t, c, s, status] = await Promise.all([
        adminApiFetch('/admin/email/templates', accessToken, appSecretProof),
        adminApiFetch('/admin/billing/clients-lookup', accessToken, appSecretProof),
        adminApiFetch('/admin/email/sent', accessToken, appSecretProof),
        adminApiFetch('/admin/email/status', accessToken, appSecretProof),
      ]);
      setTemplates(t.templates || []);
      setClients(c.clients || []);
      setSent(s.sent || []);
      setMailboxes(status.mailboxes || []);
    } catch { setError('You do not have permission to view this page.'); }
    finally { setLoading(false); }
  }
  useEffect(() => { load(); }, [accessToken, appSecretProof]); // eslint-disable-line react-hooks/exhaustive-deps
  useLiveRefresh(['email'], load);

  const infoBox = mailboxes.find((m) => m.identity === 'info');

  async function sendTest() {
    if (!accessToken || !appSecretProof) return;
    const to = window.prompt('Send a real test message from info@ to which address? (use one you can open)');
    if (!to) return;
    setTesting(true);
    try {
      await adminApiFetch('/admin/email/test', accessToken, appSecretProof, { method: 'POST', body: JSON.stringify({ identity: 'info', to }) });
      show('success', `Test message delivered to the mail server for ${to}. Check that inbox.`);
    } catch (e) { show('error', `Test failed: ${(e as Error).message}`); }
    finally { setTesting(false); load(); }
  }

  function applyTemplate(templateId: string) {
    const t = templates.find((x) => x.id === Number(templateId));
    if (!t) return;
    const client = clients.find((c) => c.id === Number(selectedClientId));
    const values = { clientName: client?.name || '{{clientName}}' };
    setForm((f) => ({ ...f, subject: fillTemplate(t.subject, values), body: fillTemplate(t.body, values) }));
  }

  function pickClient(id: string) {
    setSelectedClientId(id);
    const client = clients.find((c) => c.id === Number(id));
    if (client?.email) setForm((f) => ({ ...f, toEmail: client.email as string }));
    // Re-substitute clientName in whatever's already drafted, so picking
    // the client after the template still fills in the name correctly.
    if (client) {
      setForm((f) => ({
        ...f,
        subject: f.subject.replace(/\{\{\s*clientName\s*\}\}/g, client.name),
        body: f.body.replace(/\{\{\s*clientName\s*\}\}/g, client.name),
      }));
    }
  }

  async function send(e: React.FormEvent) {
    e.preventDefault();
    if (!accessToken || !appSecretProof) return;
    setSending(true);
    try {
      const d = await adminApiFetch('/admin/email/send', accessToken, appSecretProof, {
        method: 'POST',
        body: JSON.stringify({
          ...form, ccEmail: form.ccEmail || undefined,
          clientId: selectedClientId ? Number(selectedClientId) : undefined,
          attachments,
        }),
      });
      show('success', `Email delivered to the mail server for ${form.toEmail}.`);
      setForm(emptyForm);
      setAttachments([]);
      setSelectedClientId('');
      load();
    } catch (e) {
      const m = (e as Error).message;
      show('error', m === 'REQUEST_FAILED_503' ? 'NOT sent — the info@ mailbox has no SMTP login yet (see the banner above).' : m === 'REQUEST_FAILED_502' ? 'NOT sent — the mail server refused it. Open "Recently Sent" for the reason.' : 'Could not send that email.');
      load();
    } finally { setSending(false); }
  }

  if (error) return <p className="text-sm text-brand-red">{error}</p>;

  return (
    <div className="space-y-4">
      <h1 className="text-xl font-bold">Email &bull; admin.lussavara.co.tz</h1>

      {!loading && infoBox && (
        <div className={`rounded-xl p-3 text-xs border flex flex-wrap items-center justify-between gap-2 ${infoBox.ok ? 'bg-green-50 border-green-200 text-green-800' : 'bg-yellow-50 border-yellow-200 text-yellow-800'}`}>
          <span>
            {infoBox.ok
              ? <>Sending from <strong>{infoBox.address}</strong> — the mail server accepted the login. Messages go out in the LUSSAVARA premium template.</>
              : infoBox.configured
                ? <>Cannot log in to <strong>{infoBox.address}</strong>: {infoBox.error}. Nothing can be delivered until this is fixed in <code>services/api/.env</code>.</>
                : <>The <strong>{infoBox.address}</strong> mailbox has no SMTP login yet, so nothing can be delivered. Set <code>SMTP_HOST</code>, <code>SMTP_INFO_USER</code> and <code>SMTP_INFO_PASS</code> in <code>services/api/.env</code>.</>}
          </span>
          {infoBox.ok && <button onClick={sendTest} disabled={testing} className="border border-green-300 rounded-full px-3 py-1 font-semibold hover:bg-green-100">{testing ? 'Sending…' : 'Send a test message'}</button>}
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
        <form onSubmit={send} className="lg:col-span-2 bg-white border border-brand-border rounded-xl p-4 space-y-3">
          <div className="grid grid-cols-2 gap-2">
            <select value={selectedClientId} onChange={(e) => pickClient(e.target.value)}
              className="border border-brand-border rounded-lg px-2 py-1.5 text-sm">
              <option value="">Pick a client (optional)…</option>
              {clients.map((c) => <option key={c.id} value={c.id}>{c.name} {c.company && `• ${c.company}`}</option>)}
            </select>
            <select onChange={(e) => applyTemplate(e.target.value)} defaultValue=""
              className="border border-brand-border rounded-lg px-2 py-1.5 text-sm">
              <option value="">Use a template…</option>
              {templates.map((t) => <option key={t.id} value={t.id}>{t.category} — {t.name}</option>)}
            </select>
          </div>

          <input required type="email" placeholder="To" value={form.toEmail} onChange={(e) => setForm({ ...form, toEmail: e.target.value })}
            className="w-full border border-brand-border rounded-lg px-3 py-2 text-sm" />
          <input type="email" placeholder="CC (optional)" value={form.ccEmail} onChange={(e) => setForm({ ...form, ccEmail: e.target.value })}
            className="w-full border border-brand-border rounded-lg px-3 py-2 text-sm" />
          <input required placeholder="Subject" value={form.subject} onChange={(e) => setForm({ ...form, subject: e.target.value })}
            className="w-full border border-brand-border rounded-lg px-3 py-2 text-sm" />
          <textarea required placeholder="Write your message…" value={form.body} onChange={(e) => setForm({ ...form, body: e.target.value })}
            rows={10} className="w-full border border-brand-border rounded-lg px-3 py-2 text-sm" />
          <AiPolishButton text={form.body} kind="email" onAccept={(t) => setForm((f) => ({ ...f, body: t }))} />

          <AttachmentPicker attachments={attachments} onChange={setAttachments} />

          <button disabled={sending} className="w-full bg-brand-red text-white text-sm font-semibold py-2.5 rounded-lg disabled:opacity-60 transition-transform hover:scale-[1.01]">
            {sending ? 'Sending…' : 'Send from info@lussavara.co.tz'}
          </button>
        </form>

        <div className="bg-white border border-brand-border rounded-xl p-4">
          <p className="text-sm font-semibold mb-2">Recently Sent</p>
          {loading ? <TableSkeleton rows={4} cols={1} /> : (
            <div className="space-y-2 max-h-[500px] overflow-y-auto">
              {sent.map((s) => (
                <div key={s.id} className="text-xs border-t border-brand-border pt-2 first:border-t-0 first:pt-0 animate-fadeInUp">
                  <div className="flex justify-between items-start gap-2">
                    <p className="font-medium truncate">{s.subject}</p>
                    <span className={`text-[9px] px-1.5 py-0.5 rounded-full shrink-0 ${
                      s.status === 'SENT' ? 'bg-green-100 text-green-700' : s.status === 'FAILED' ? 'bg-red-100 text-red-700' : 'bg-yellow-100 text-yellow-700'
                    }`}>{s.status === 'QUEUED' ? 'NOT DELIVERED' : s.status}</span>
                  </div>
                  <p className="text-gray-400">{s.toEmail} &bull; {new Date(s.createdAt).toLocaleString()}{s.fromIdentity ? ` \u2022 ${s.fromIdentity}@` : ''}</p>
                  {s.errorMessage && <p className="text-[10px] text-brand-red mt-0.5">{s.errorMessage}</p>}
                </div>
              ))}
              {sent.length === 0 && <p className="text-xs text-gray-400">Nothing sent yet.</p>}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
