import { useState, useEffect } from 'react';
import { toast } from 'sonner';
import { Plus, Trash2, Loader2, Mail, Server, KeyRound, RefreshCw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';
import { useJobs } from 'hooks/useJobs';

type EmailAccountRow = {
  id: number;
  provider: string;
  email: string;
  displayName: string | null;
  enabled: boolean;
  status: string;
  createdAt: string;
};

type ProviderChoice = 'gmail-oauth' | 'gmail-password' | 'imap';

type FormState = {
  email: string;
  displayName: string;
  password: string;
  imapHost: string;
  imapPort: string;
  imapSecure: boolean;
};

const INITIAL_FORM: FormState = {
  email: '',
  displayName: '',
  password: '',
  imapHost: '',
  imapPort: '993',
  imapSecure: true,
};

export const EmailAccounts = () => {
  const client = useClient();
  const { user } = useAuth();
  const { jobs } = useJobs({ type: 'email-sync' });
  const [accounts, setAccounts] = useState<EmailAccountRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [showPicker, setShowPicker] = useState(false);
  const [activeForm, setActiveForm] = useState<ProviderChoice | null>(null);
  const [form, setForm] = useState<FormState>(INITIAL_FORM);
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState<number | null>(null);
  const [syncing, setSyncing] = useState<number | null>(null);

  const fetchAccounts = () => {
    client
      .get<EmailAccountRow[]>('/email/accounts')
      .then(setAccounts)
      .catch(() => {})
      .finally(() => setLoading(false));
  };

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

  // Poll accounts while any are queued/syncing to pick up status changes
  const hasSyncingAccount = accounts.some((a) => a.status === 'syncing' || a.status === 'queued');
  useEffect(() => {
    if (!hasSyncingAccount) return;
    const interval = setInterval(fetchAccounts, 5000);
    return () => clearInterval(interval);
  }, [hasSyncingAccount]);

  const resetForm = () => {
    setActiveForm(null);
    setShowPicker(false);
    setForm(INITIAL_FORM);
  };

  const handlePickProvider = (choice: ProviderChoice) => {
    setShowPicker(false);
    setActiveForm(choice);
    if (choice === 'gmail-oauth' || choice === 'gmail-password') {
      setForm({ ...INITIAL_FORM, imapHost: 'imap.gmail.com', imapPort: '993', imapSecure: true });
    } else {
      setForm(INITIAL_FORM);
    }
  };

  const handleGmailOAuth = async () => {
    setSaving(true);
    try {
      const status = await client.get<{ connected: boolean; email: string | null }>('/integrations/google/status');
      if (!status.connected) {
        const params = new URLSearchParams({ token: client.token ?? '', origin: window.location.origin });
        window.location.href = `/api/integrations/google/authorize?${params.toString()}`;
        return;
      }

      const result = await client.post<{ id: number; provider: string; email: string }>('/email/accounts', {
        provider: 'gmail',
        email: status.email,
        displayName: form.displayName || undefined,
        imapHost: 'imap.gmail.com',
        imapPort: 993,
        imapSecure: true,
        authType: 'oauth',
        credentials: { userIntegrationId: true },
      });

      toast.success(`Added ${result.email}`);
      resetForm();
      fetchAccounts();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to add Gmail account');
    } finally {
      setSaving(false);
    }
  };

  const handlePasswordSubmit = async () => {
    if (!form.email.trim() || !form.password.trim()) return;
    setSaving(true);
    try {
      const provider = form.imapHost === 'imap.gmail.com' ? 'gmail' : 'imap';
      const result = await client.post<{ id: number; provider: string; email: string }>('/email/accounts', {
        provider,
        email: form.email.trim(),
        displayName: form.displayName.trim() || undefined,
        imapHost: form.imapHost,
        imapPort: Number(form.imapPort),
        imapSecure: form.imapSecure,
        authType: 'password',
        credentials: { password: form.password },
      });

      toast.success(`Added ${result.email}`);
      resetForm();
      fetchAccounts();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to add account');
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (id: number) => {
    setDeleting(id);
    try {
      await client.delete(`/email/accounts/${id}`);
      setAccounts((prev) => prev.filter((a) => a.id !== id));
      toast.success('Account removed');
    } catch {
      toast.error('Failed to remove account');
    } finally {
      setDeleting(null);
    }
  };

  const handleSync = async (id: number) => {
    setSyncing(id);
    try {
      const result = await client.post<{ ok: boolean; saved?: number }>(`/email/accounts/${id}/sync`, {});
      if (result.saved !== undefined) {
        toast.success(result.saved > 0 ? `${result.saved} new emails` : 'No new emails');
      } else {
        toast.success('Sync started');
        setAccounts((prev) => prev.map((a) => (a.id === id ? { ...a, status: 'queued' } : a)));
      }
      fetchAccounts();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to sync');
    } finally {
      setSyncing(null);
    }
  };

  if (loading) return null;

  return (
    <div className="grid gap-4">
      <div>
        <p className="text-sm font-medium text-duck-dark dark:text-foreground">Email Accounts</p>
        <p className="text-xs text-duck-dark/50 dark:text-foreground/50 mt-1">
          Connect email accounts for syncing your inbox. Supports Gmail and any IMAP provider.
        </p>
      </div>

      {/* Account list */}
      {accounts.length > 0 && (
        <div className="grid gap-2">
          {accounts.map((account) => {
            const accountJob = jobs.find(
              (j) =>
                (j.status === 'queued' || j.status === 'running') &&
                (j.meta as Record<string, unknown> | undefined)?.emailAccountId === account.id,
            );
            const progress = accountJob?.steps[accountJob.currentStep]?.progress;

            return (
              <div key={account.id} className="rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3">
                <div className="flex items-center gap-3">
                  <ProviderIcon provider={account.provider} />
                  <div className="min-w-0 flex-1">
                    <p className="text-sm font-medium text-duck-dark dark:text-foreground truncate">
                      {account.displayName ?? account.email}
                    </p>
                    {account.displayName && (
                      <p className="text-xs text-duck-dark/50 dark:text-foreground/50 truncate">{account.email}</p>
                    )}
                  </div>
                  <StatusBadge status={account.status} />
                  {account.status === 'queued' && (
                    <span className="text-xs text-duck-dark/50 dark:text-foreground/50">Waiting...</span>
                  )}
                  {(account.status === 'connected' || account.status === 'synced') && (
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => handleSync(account.id)}
                      disabled={syncing === account.id}
                      className="h-7 text-xs cursor-pointer gap-1.5"
                    >
                      {syncing === account.id ? (
                        <Loader2 className="h-3 w-3 animate-spin" />
                      ) : (
                        <RefreshCw className="h-3 w-3" />
                      )}
                      Sync
                    </Button>
                  )}
                  <button
                    onClick={() => handleDelete(account.id)}
                    disabled={deleting === account.id || account.status === 'syncing' || account.status === 'queued'}
                    className="text-duck-dark/40 dark:text-foreground/40 hover:text-red-500 transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed"
                  >
                    {deleting === account.id ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <Trash2 className="h-4 w-4" />
                    )}
                  </button>
                </div>
                {/* Sync progress */}
                {account.status === 'syncing' && progress && (
                  <div className="mt-2 flex items-center gap-2">
                    <Loader2 className="h-3 w-3 animate-spin text-blue-500 shrink-0" />
                    <p className="text-xs text-duck-dark/60 dark:text-foreground/60 truncate">
                      {progress.label ?? 'Syncing...'}
                    </p>
                  </div>
                )}
                {account.status === 'syncing' && !progress && (
                  <div className="mt-2 flex items-center gap-2">
                    <Loader2 className="h-3 w-3 animate-spin text-blue-500 shrink-0" />
                    <p className="text-xs text-duck-dark/60 dark:text-foreground/60">Syncing...</p>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {/* Provider picker */}
      {showPicker && !activeForm && (
        <div className="grid gap-2">
          <button
            onClick={() => handlePickProvider('gmail-oauth')}
            className="flex items-center gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3 hover:bg-duck-dark/5 dark:hover:bg-foreground/5 transition-colors cursor-pointer text-left"
          >
            <Mail className="h-4 w-4 text-duck-dark/60 dark:text-foreground/60" />
            <div>
              <p className="text-sm font-medium text-duck-dark dark:text-foreground">Gmail (OAuth)</p>
              <p className="text-xs text-duck-dark/50 dark:text-foreground/50">Uses your existing Google connection</p>
            </div>
          </button>
          <button
            onClick={() => handlePickProvider('gmail-password')}
            className="flex items-center gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3 hover:bg-duck-dark/5 dark:hover:bg-foreground/5 transition-colors cursor-pointer text-left"
          >
            <KeyRound className="h-4 w-4 text-duck-dark/60 dark:text-foreground/60" />
            <div>
              <p className="text-sm font-medium text-duck-dark dark:text-foreground">Gmail (App Password)</p>
              <p className="text-xs text-duck-dark/50 dark:text-foreground/50">
                Direct IMAP with a Google App Password
              </p>
            </div>
          </button>
          <button
            onClick={() => handlePickProvider('imap')}
            className="flex items-center gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-3 hover:bg-duck-dark/5 dark:hover:bg-foreground/5 transition-colors cursor-pointer text-left"
          >
            <Server className="h-4 w-4 text-duck-dark/60 dark:text-foreground/60" />
            <div>
              <p className="text-sm font-medium text-duck-dark dark:text-foreground">IMAP Account</p>
              <p className="text-xs text-duck-dark/50 dark:text-foreground/50">Any email provider with IMAP access</p>
            </div>
          </button>
          <Button type="button" variant="ghost" onClick={resetForm} className="h-9 cursor-pointer">
            Cancel
          </Button>
        </div>
      )}

      {/* Gmail OAuth form */}
      {activeForm === 'gmail-oauth' && (
        <div className="grid gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-4">
          <p className="text-sm font-medium text-duck-dark dark:text-foreground">Add Gmail (OAuth)</p>
          <input
            type="text"
            value={form.displayName}
            onChange={(ev) => setForm({ ...form, displayName: ev.target.value })}
            placeholder="Display name (optional)"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <div className="flex gap-2">
            <Button type="button" variant="ghost" onClick={resetForm} className="h-9 cursor-pointer">
              Cancel
            </Button>
            <Button type="button" onClick={handleGmailOAuth} disabled={saving} className="h-9 flex-1 cursor-pointer">
              {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Connect & Add'}
            </Button>
          </div>
        </div>
      )}

      {/* Gmail App Password form */}
      {activeForm === 'gmail-password' && (
        <div className="grid gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-4">
          <p className="text-sm font-medium text-duck-dark dark:text-foreground">Add Gmail (App Password)</p>
          <div className="text-xs text-duck-dark/50 dark:text-foreground/50 grid gap-1.5">
            <p>To create an App Password:</p>
            <ol className="list-decimal ml-4 grid gap-0.5">
              <li>
                Go to{' '}
                <a
                  href="https://myaccount.google.com/apppasswords"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="underline hover:opacity-70"
                >
                  Google App Passwords
                </a>
              </li>
              <li>You may need to enable 2-Step Verification first</li>
              <li>Enter a name (e.g. "Officer") and click Create</li>
              <li>Copy the 16-character password and paste it below</li>
            </ol>
          </div>
          <input
            type="email"
            value={form.email}
            onChange={(ev) => setForm({ ...form, email: ev.target.value })}
            placeholder="your@gmail.com"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <input
            type="text"
            value={form.displayName}
            onChange={(ev) => setForm({ ...form, displayName: ev.target.value })}
            placeholder="Display name (optional)"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <input
            type="password"
            value={form.password}
            onChange={(ev) => setForm({ ...form, password: ev.target.value })}
            placeholder="xxxx xxxx xxxx xxxx"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <div className="flex gap-2">
            <Button type="button" variant="ghost" onClick={resetForm} className="h-9 cursor-pointer">
              Cancel
            </Button>
            <Button
              type="button"
              onClick={handlePasswordSubmit}
              disabled={!form.email.trim() || !form.password.trim() || saving}
              className="h-9 flex-1 cursor-pointer"
            >
              {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Test & Save'}
            </Button>
          </div>
        </div>
      )}

      {/* Generic IMAP form */}
      {activeForm === 'imap' && (
        <div className="grid gap-3 rounded-lg border border-duck-dark/10 dark:border-foreground/10 p-4">
          <p className="text-sm font-medium text-duck-dark dark:text-foreground">Add IMAP Account</p>
          <input
            type="email"
            value={form.email}
            onChange={(ev) => setForm({ ...form, email: ev.target.value })}
            placeholder="you@example.com"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <input
            type="text"
            value={form.displayName}
            onChange={(ev) => setForm({ ...form, displayName: ev.target.value })}
            placeholder="Display name (optional)"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <div className="grid grid-cols-[1fr_auto_auto] gap-2">
            <input
              type="text"
              value={form.imapHost}
              onChange={(ev) => setForm({ ...form, imapHost: ev.target.value })}
              placeholder="imap.example.com"
              className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
            />
            <input
              type="number"
              value={form.imapPort}
              onChange={(ev) => setForm({ ...form, imapPort: ev.target.value })}
              placeholder="993"
              className="h-9 w-20 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
            />
            <label className="flex items-center gap-1.5 text-xs text-duck-dark/60 dark:text-foreground/60 cursor-pointer">
              <input
                type="checkbox"
                checked={form.imapSecure}
                onChange={(ev) => setForm({ ...form, imapSecure: ev.target.checked })}
                className="cursor-pointer"
              />
              SSL
            </label>
          </div>
          <input
            type="password"
            value={form.password}
            onChange={(ev) => setForm({ ...form, password: ev.target.value })}
            placeholder="Password"
            className="h-9 rounded-md border border-duck-dark/10 dark:border-foreground/10 bg-transparent px-3 text-sm"
          />
          <div className="flex gap-2">
            <Button type="button" variant="ghost" onClick={resetForm} className="h-9 cursor-pointer">
              Cancel
            </Button>
            <Button
              type="button"
              onClick={handlePasswordSubmit}
              disabled={!form.email.trim() || !form.password.trim() || !form.imapHost.trim() || saving}
              className="h-9 flex-1 cursor-pointer"
            >
              {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Test & Save'}
            </Button>
          </div>
        </div>
      )}

      {/* Add account button */}
      {!showPicker && !activeForm && (
        <Button
          type="button"
          variant="outline"
          onClick={() => setShowPicker(true)}
          className="w-full h-11 cursor-pointer gap-2"
        >
          <Plus className="h-4 w-4" />
          Add Account
        </Button>
      )}
    </div>
  );
};

const StatusBadge = ({ status }: { status: string }) => {
  switch (status) {
    case 'connected':
      return (
        <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-yellow-500/10 text-yellow-600 dark:text-yellow-400">
          Connected
        </span>
      );
    case 'queued':
      return (
        <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-orange-500/10 text-orange-600 dark:text-orange-400">
          Queued
        </span>
      );
    case 'syncing':
      return (
        <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400">
          Syncing
        </span>
      );
    case 'synced':
      return (
        <span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-green-500/10 text-green-600 dark:text-green-400">
          Synced
        </span>
      );
    default:
      return null;
  }
};

const ProviderIcon = ({ provider }: { provider: string }) => {
  switch (provider) {
    case 'gmail':
      return <Mail className="h-4 w-4 text-red-500 shrink-0" />;
    case 'outlook':
      return <Mail className="h-4 w-4 text-blue-500 shrink-0" />;
    default:
      return <Server className="h-4 w-4 text-duck-dark/60 dark:text-foreground/60 shrink-0" />;
  }
};
