'use client';

import { useEffect, useState, useCallback } from 'react';
import { Loader2, Save, Mail, Send, Trash2, Eye, EyeOff, ChevronDown, AlertCircle, Check } from 'lucide-react';
import { toast } from 'sonner';
import { useLanguage } from '@client/contexts/LanguageContext';

interface SmtpView {
  enabled: boolean;
  host: string;
  port: number;
  user: string;
  from: string;
  secure: boolean;
  passSet: boolean;
}

const DEFAULTS: SmtpView = {
  enabled: false,
  host: '',
  port: 587,
  user: '',
  from: '',
  secure: false,
  passSet: false,
};

interface BranchSmtpForm {
  smtp_host: string;
  smtp_port: string;
  smtp_user: string;
  smtp_pass: string;
  smtp_from: string;
}

const EMPTY_BRANCH_SMTP: BranchSmtpForm = { smtp_host: '', smtp_port: '587', smtp_user: '', smtp_pass: '', smtp_from: '' };

function BranchSmtpCard() {
  const { t } = useLanguage();
  const [branches, setBranches] = useState<{ id: string; name: string; smtpConfigured: boolean }[]>([]);
  const [selectedBranchId, setSelectedBranchId] = useState<string>('');
  const [form, setForm] = useState<BranchSmtpForm>(EMPTY_BRANCH_SMTP);
  const [showPass, setShowPass] = useState(false);
  const [loadingBranches, setLoadingBranches] = useState(true);
  const [loadingSmtp, setLoadingSmtp] = useState(false);
  const [saving, setSaving] = useState(false);
  const [clearing, setClearing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [configured, setConfigured] = useState(false);

  const refreshBranches = useCallback(async () => {
    try {
      const res = await fetch('/api/branches', { credentials: 'include' });
      const json = await res.json() as { branches?: Record<string, unknown>[] };
      const rows = (json.branches ?? []) as Record<string, unknown>[];
      setBranches(rows.map(b => ({
        id: String(b.id ?? ''),
        name: String(b.name ?? ''),
        smtpConfigured: !!(b.smtp_host && b.smtp_user && b.smtp_pass_status),
      })));
    } catch { /* ignore */ } finally { setLoadingBranches(false); }
  }, []);

  useEffect(() => { refreshBranches(); }, [refreshBranches]);

  const loadBranchSmtp = useCallback(async (branchId: string) => {
    setLoadingSmtp(true);
    setError(null);
    try {
      const res = await fetch(`/api/branches/${branchId}`, { credentials: 'include' });
      const json = await res.json() as { branch: Record<string, unknown> };
      const b = json.branch;
      const hasSmtp = !!(b.smtp_host && b.smtp_user && b.smtp_pass_status);
      setConfigured(hasSmtp);
      setForm({
        smtp_host: String(b.smtp_host ?? ''),
        smtp_port: String(b.smtp_port ?? '587'),
        smtp_user: String(b.smtp_user ?? ''),
        smtp_pass: '',
        smtp_from: String(b.smtp_from ?? ''),
      });
    } catch {
      setError(t('smtp.errors.loadBranch', 'Failed to load branch SMTP settings'));
    } finally {
      setLoadingSmtp(false);
    }
  }, []);

  const handleBranchChange = (id: string) => {
    setSelectedBranchId(id);
    setError(null);
    setSuccess(null);
    if (id) loadBranchSmtp(id);
    else { setForm(EMPTY_BRANCH_SMTP); setConfigured(false); }
  };

  const handleSave = async () => {
    if (!selectedBranchId) return;
    setSaving(true);
    setError(null);
    try {
      const body: Record<string, unknown> = {
        smtp_host: form.smtp_host || null,
        smtp_port: form.smtp_port ? parseInt(form.smtp_port, 10) : null,
        smtp_user: form.smtp_user || null,
        smtp_from: form.smtp_from || null,
      };
      if (form.smtp_pass) body.smtp_pass = form.smtp_pass;
      const res = await fetch(`/api/branches/${selectedBranchId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        const json = await res.json() as { error?: string };
        throw new Error(json.error || t('common.saveFailed', 'Save failed'));
      }
      const isConfigured = !!(form.smtp_host && form.smtp_user && (form.smtp_pass || configured));
      setConfigured(isConfigured);
      setForm(f => ({ ...f, smtp_pass: '' }));
      setBranches(prev => prev.map(b => b.id === selectedBranchId ? { ...b, smtpConfigured: isConfigured } : b));
      setSuccess(t('smtp.success.saved', 'SMTP settings saved'));
      setTimeout(() => setSuccess(null), 3000);
    } catch (err) {
      setError(err instanceof Error ? err.message : t('common.failedToSave', 'Failed to save'));
    } finally {
      setSaving(false);
    }
  };

  const handleClear = async () => {
    if (!selectedBranchId) return;
    setClearing(true);
    setError(null);
    try {
      const res = await fetch(`/api/branches/${selectedBranchId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ smtp_host: null, smtp_port: null, smtp_user: null, smtp_pass: null, smtp_from: null }),
      });
      if (!res.ok) {
        const json = await res.json() as { error?: string };
        throw new Error(json.error || t('smtp.errors.clearFailed', 'Clear failed'));
      }
      setForm(EMPTY_BRANCH_SMTP);
      setConfigured(false);
      setBranches(prev => prev.map(b => b.id === selectedBranchId ? { ...b, smtpConfigured: false } : b));
      setSuccess(t('smtp.success.cleared', 'Branch SMTP cleared — will fall back to tenant settings'));
      setTimeout(() => setSuccess(null), 3000);
    } catch (err) {
      setError(err instanceof Error ? err.message : t('smtp.errors.failedToClear', 'Failed to clear'));
    } finally {
      setClearing(false);
    }
  };

  return (
    <div className="card p-5">
      <div className="flex items-center gap-3 mb-2">
        <Mail size={18} style={{ color: 'hsl(var(--primary))' }} />
        <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>{t('smtp.branchOverrides.title', 'Per-Branch SMTP Overrides')}</h3>
      </div>
      <p className="text-sm mb-4" style={{ color: 'hsl(var(--muted-foreground))' }}>
        {t('smtp.branchOverrides.description', 'Override the tenant SMTP for a specific branch. Useful when different branches use different sending domains. If not set, the branch falls back to the tenant SMTP above.')}
      </p>

      {error && (
        <div className="flex items-center gap-2 p-3 rounded-lg text-sm mb-3" style={{ backgroundColor: 'hsl(0, 84%, 95%)', color: 'hsl(0, 84%, 40%)' }}>
          <AlertCircle size={14} />{error}
        </div>
      )}
      {success && (
        <div className="flex items-center gap-2 p-3 rounded-lg text-sm mb-3" style={{ backgroundColor: 'hsl(142, 72%, 95%)', color: 'hsl(142, 72%, 29%)' }}>
          <Check size={14} />{success}
        </div>
      )}

      <div className="relative mb-4">
        <select
          value={selectedBranchId}
          onChange={e => handleBranchChange(e.target.value)}
          disabled={loadingBranches}
          className="w-full px-3 py-2 pr-8 text-sm rounded-md border outline-none appearance-none"
          style={{ borderColor: 'hsl(var(--border))' }}
        >
          <option value="">{loadingBranches ? t('smtp.loadingBranches', 'Loading branches…') : t('smtp.selectBranch', '— Select a branch —')}</option>
          {branches.map(b => (
            <option key={b.id} value={b.id}>{b.name}{b.smtpConfigured ? ' ✓' : ''}</option>
          ))}
        </select>
        <ChevronDown size={14} className="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none" style={{ color: 'hsl(var(--muted-foreground))' }} />
      </div>

      {selectedBranchId && (
        loadingSmtp ? (
          <div className="flex items-center gap-2 py-4 text-sm" style={{ color: 'hsl(var(--muted-foreground))' }}>
            <Loader2 size={14} className="animate-spin" />{t('common.loading', 'Loading…')}
          </div>
        ) : (
          <div className="space-y-3">
            <div className="grid grid-cols-2 gap-4">
              <Field
                label={t('smtp.fields.host', 'SMTP Host')}
                value={form.smtp_host}
                onChange={v => setForm(f => ({ ...f, smtp_host: v }))}
                placeholder="smtp.example.com"
              />
              <Field
                label={t('smtp.fields.port', 'Port')}
                type="number"
                value={form.smtp_port}
                onChange={v => setForm(f => ({ ...f, smtp_port: v }))}
                placeholder="587"
              />
            </div>
            <Field
              label={t('smtp.fields.username', 'Username')}
              value={form.smtp_user}
              onChange={v => setForm(f => ({ ...f, smtp_user: v }))}
              placeholder="user@example.com"
            />
            <label className="block">
              <span className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>
                {configured ? t('smtp.fields.passwordKeepLabel', 'Password (stored — leave blank to keep)') : t('smtp.fields.password', 'Password')}
              </span>
              <div className="relative">
                <input
                  className="w-full border rounded-md px-3 py-2 pr-10 text-sm"
                  type={showPass ? 'text' : 'password'}
                  value={form.smtp_pass}
                  placeholder={configured ? t('smtp.fields.passwordKeep', 'Leave blank to keep existing password') : t('smtp.fields.passwordPlaceholder', 'SMTP password or app password')}
                  onChange={e => setForm(f => ({ ...f, smtp_pass: e.target.value }))}
                  style={{ borderColor: 'hsl(var(--border))' }}
                />
                <button type="button" onClick={() => setShowPass(v => !v)} className="absolute right-2 top-1/2 -translate-y-1/2 p-1">
                  {showPass
                    ? <EyeOff size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />
                    : <Eye size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />}
                </button>
              </div>
            </label>
            <Field
              label={t('smtp.fields.fromAddress', 'From Address')}
              value={form.smtp_from}
              onChange={v => setForm(f => ({ ...f, smtp_from: v }))}
              placeholder={t('smtp.fields.fromPlaceholder', 'noreply@example.com (optional, defaults to username)')}
            />
            <div className="flex justify-between items-center pt-1">
              {configured ? (
                <button
                  type="button"
                  onClick={handleClear}
                  disabled={clearing || saving}
                  className="inline-flex items-center gap-2 text-sm px-3 py-2 rounded-md border disabled:opacity-50"
                  style={{ borderColor: 'hsl(var(--border))', color: 'hsl(var(--danger))' }}
                >
                  {clearing ? <Loader2 size={14} className="animate-spin" /> : <Trash2 size={14} />}
                  {t('smtp.actions.clearBranch', 'Clear branch override')}
                </button>
              ) : <span />}
              <button
                type="button"
                disabled={saving || clearing}
                onClick={handleSave}
                className="btn-primary"
              >
                {saving ? <Loader2 size={15} className="animate-spin" /> : <Save size={15} />}
                {saving ? t('common.saving', 'Saving…') : t('common.save', 'Save')}
              </button>
            </div>
          </div>
        )
      )}
    </div>
  );
}

export default function EmailSmtpTab() {
  const [smtp, setSmtp] = useState<SmtpView>(DEFAULTS);
  const [pass, setPass] = useState('');
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [clearing, setClearing] = useState(false);
  const [testTo, setTestTo] = useState('');
  const [testing, setTesting] = useState(false);

  useEffect(() => {
    fetch('/api/restaurant/email/smtp', { credentials: 'include' })
      .then((r) => r.json())
      .then((d) => {
        if (d?.smtp) setSmtp({ ...DEFAULTS, ...d.smtp });
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  const save = async () => {
    setSaving(true);
    try {
      const body: Record<string, unknown> = {
        enabled: smtp.enabled,
        host: smtp.host,
        port: smtp.port,
        user: smtp.user,
        from: smtp.from,
        secure: !!smtp.secure,
      };
      if (pass) body.pass = pass;
      const r = await fetch('/api/restaurant/email/smtp', {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      const json = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(json?.error || 'Save failed');
      toast.success('SMTP settings saved');
      setPass('');
      if (json?.smtp) setSmtp({ ...DEFAULTS, ...json.smtp });
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Save failed');
    } finally {
      setSaving(false);
    }
  };

  const clearAll = async () => {
    if (!confirm('Clear tenant SMTP settings and revert to platform defaults?')) return;
    setClearing(true);
    try {
      const r = await fetch('/api/restaurant/email/smtp', { method: 'DELETE', credentials: 'include' });
      if (!r.ok) throw new Error((await r.json())?.error || 'Clear failed');
      toast.success('Tenant SMTP cleared — platform defaults will be used');
      setSmtp(DEFAULTS);
      setPass('');
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Clear failed');
    } finally {
      setClearing(false);
    }
  };

  const sendTest = async () => {
    if (!testTo) return toast.error('Enter a recipient email');
    setTesting(true);
    try {
      const r = await fetch('/api/restaurant/email/smtp', {
        method: 'PUT',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ to: testTo }),
      });
      if (!r.ok) throw new Error((await r.json())?.error || 'Test failed');
      toast.success('Test email sent');
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Test failed');
    } finally {
      setTesting(false);
    }
  };

  if (loading) {
    return (
      <div className="p-8 flex justify-center">
        <Loader2 className="animate-spin" />
      </div>
    );
  }

  return (
    <div className="max-w-3xl space-y-6">
      <div className="card p-5">
        <div className="flex items-center gap-3 mb-3">
          <Mail size={18} style={{ color: 'hsl(var(--primary))' }} />
          <h3 className="font-semibold" style={{ color: 'hsl(var(--foreground))' }}>
            Tenant SMTP
          </h3>
        </div>
        <p className="text-sm mb-4" style={{ color: 'hsl(var(--muted-foreground))' }}>
          Send branded emails from your own domain (e.g. <code>no-reply@yourdomain.com</code>). When the
          toggle below is off, emails fall back to the platform&apos;s default SMTP. Passwords are encrypted
          at rest.
        </p>

        <label className="flex items-center gap-2 mb-4 text-sm">
          <input
            type="checkbox"
            checked={smtp.enabled}
            onChange={(e) => setSmtp({ ...smtp, enabled: e.target.checked })}
          />
          Use my SMTP for outbound emails
        </label>

        <div className="grid grid-cols-2 gap-4">
          <Field
            label="SMTP host"
            value={smtp.host}
            onChange={(v) => setSmtp({ ...smtp, host: v })}
            placeholder="smtp.sendgrid.net"
          />
          <Field
            label="Port"
            type="number"
            value={String(smtp.port)}
            onChange={(v) => setSmtp({ ...smtp, port: Number(v) || 587 })}
          />
        </div>

        <label className="flex items-center gap-2 text-sm mt-3">
          <input
            type="checkbox"
            checked={smtp.secure}
            onChange={(e) => setSmtp({ ...smtp, secure: e.target.checked })}
          />
          Use TLS (secure)
        </label>

        <div className="mt-3 space-y-3">
          <Field label="Username" value={smtp.user} onChange={(v) => setSmtp({ ...smtp, user: v })} />
          <Field
            label={`Password ${smtp.passSet ? '(stored — leave blank to keep)' : ''}`}
            type="password"
            value={pass}
            onChange={setPass}
            placeholder={smtp.passSet ? '••••••••' : ''}
          />
          <Field
            label='From (e.g. "My Restaurant <no-reply@yourdomain.com>")'
            value={smtp.from}
            onChange={(v) => setSmtp({ ...smtp, from: v })}
            placeholder="My Restaurant <no-reply@yourdomain.com>"
          />
        </div>

        <div className="flex justify-between items-center mt-5">
          <button
            type="button"
            onClick={clearAll}
            disabled={clearing}
            className="inline-flex items-center gap-2 text-sm px-3 py-2 rounded-md border disabled:opacity-50"
            style={{ borderColor: 'hsl(var(--border))', color: 'hsl(var(--danger))' }}
          >
            {clearing ? <Loader2 size={14} className="animate-spin" /> : <Trash2 size={14} />}
            Clear & use platform default
          </button>
          <button
            type="button"
            disabled={saving}
            onClick={save}
            className="btn-primary"
          >
            {saving ? <Loader2 size={15} className="animate-spin" /> : <Save size={15} />}
            {saving ? 'Saving…' : 'Save'}
          </button>
        </div>
      </div>

      <BranchSmtpCard />

      <div className="card p-5">
        <h3 className="font-semibold flex items-center gap-2 mb-2" style={{ color: 'hsl(var(--foreground))' }}>
          <Send size={16} /> Send a test email
        </h3>
        <p className="text-xs mb-3" style={{ color: 'hsl(var(--muted-foreground))' }}>
          Sends a sample template to the address below using your saved tenant SMTP. Save first if you just
          changed credentials.
        </p>
        <div className="flex gap-2">
          <input
            className="flex-1 border rounded-md px-3 py-2 text-sm"
            type="email"
            placeholder="you@example.com"
            value={testTo}
            onChange={(e) => setTestTo(e.target.value)}
            style={{ borderColor: 'hsl(var(--border))' }}
          />
          <button
            type="button"
            disabled={testing}
            onClick={sendTest}
            className="btn-secondary"
          >
            {testing ? <Loader2 size={14} className="animate-spin" /> : <Send size={14} />}
            {testing ? 'Sending…' : 'Send test'}
          </button>
        </div>
      </div>
    </div>
  );
}

function Field({
  label,
  value,
  onChange,
  type = 'text',
  placeholder,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  type?: string;
  placeholder?: string;
}) {
  return (
    <label className="block">
      <span className="block text-xs font-semibold mb-1.5" style={{ color: 'hsl(var(--foreground-secondary))' }}>
        {label}
      </span>
      <input
        className="w-full border rounded-md px-3 py-2 text-sm"
        type={type}
        value={value}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
        style={{ borderColor: 'hsl(var(--border))' }}
      />
    </label>
  );
}
