import { useState, useEffect } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { useClient } from 'hooks/useClient';
import { useAuth } from 'hooks/useAuth';

type Provider = 'resend' | 'smtp' | 'mailhog';

type SmtpConfig = {
  provider: Provider;
  apiKey?: string;
  host?: string;
  port?: number;
  username?: string;
  password?: string;
  secure?: boolean;
  fromName: string;
  fromEmail: string;
};

const PROVIDER_DEFAULTS: Record<Provider, Partial<SmtpConfig>> = {
  mailhog: { host: 'localhost', port: 1025, secure: false, username: '', password: '' },
  resend: { apiKey: '' },
  smtp: { host: '', port: 587, secure: false, username: '', password: '' },
};

export const SMTPSection = () => {
  const client = useClient();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const { data: config, isLoading } = useQuery({
    queryKey: ['SMTP_CONFIG'],
    queryFn: () => client.get<SmtpConfig | null>('/server-settings/smtp'),
  });

  const [provider, setProvider] = useState<Provider>('mailhog');
  const [apiKey, setApiKey] = useState('');
  const [host, setHost] = useState('localhost');
  const [port, setPort] = useState('1025');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [secure, setSecure] = useState(false);
  const [fromName, setFromName] = useState('officerdev');
  const [fromEmail, setFromEmail] = useState('no-reply@officer.dev');
  const [isSaving, setIsSaving] = useState(false);
  const [isTestingConnection, setIsTestingConnection] = useState(false);
  const [testEmail, setTestEmail] = useState(user?.email ?? '');
  const [isTesting, setIsTesting] = useState(false);

  useEffect(() => {
    if (!config) return;
    setProvider(config.provider);
    setApiKey(config.apiKey ?? '');
    setHost(config.host ?? '');
    setPort(String(config.port ?? 587));
    setUsername(config.username ?? '');
    setPassword(config.password ?? '');
    setSecure(config.secure ?? false);
    setFromName(config.fromName || 'officerdev');
    setFromEmail(config.fromEmail || 'no-reply@officer.dev');
  }, [config]);

  const handleProviderChange = (v: Provider) => {
    setProvider(v);
    const defaults = PROVIDER_DEFAULTS[v];
    if (defaults.host !== undefined) setHost(defaults.host);
    if (defaults.port !== undefined) setPort(String(defaults.port));
    if (defaults.secure !== undefined) setSecure(defaults.secure);
    if (defaults.username !== undefined) setUsername(defaults.username);
    if (defaults.password !== undefined) setPassword(defaults.password);
    if (defaults.apiKey !== undefined) setApiKey(defaults.apiKey);
  };

  const buildConfig = (): SmtpConfig => ({
    provider,
    fromName,
    fromEmail,
    ...(provider === 'resend' ? { apiKey } : { host, port: parseInt(port) || 587, username, password, secure }),
  });

  const handleSave = async () => {
    if (isSaving) return;
    setIsSaving(true);
    try {
      await client.put('/server-settings/smtp', buildConfig());
      queryClient.invalidateQueries({ queryKey: ['SMTP_CONFIG'] });
      toast.success('SMTP settings saved');
    } catch {
      toast.error('Failed to save SMTP settings');
    } finally {
      setIsSaving(false);
    }
  };

  const handleTestConnection = async () => {
    if (isTestingConnection) return;
    setIsTestingConnection(true);
    try {
      await client.post('/server-settings/smtp/test-connection');
      toast.success('Connection successful');
    } catch (err: unknown) {
      const raw = (err as { message?: string })?.message;
      let msg = 'Connection failed';
      try {
        if (raw) msg = JSON.parse(raw).error ?? msg;
      } catch {
        /* ignore */
      }
      toast.error(msg);
    } finally {
      setIsTestingConnection(false);
    }
  };

  const handleTest = async () => {
    if (isTesting || !testEmail) return;
    setIsTesting(true);
    try {
      const result = await client.post<{ success?: boolean; error?: string }>('/server-settings/smtp/test', {
        ...buildConfig(),
        to: testEmail,
      });
      if (result.error) {
        toast.error(result.error);
      } else {
        toast.success(`Test email sent to ${testEmail}`);
      }
    } catch (err: unknown) {
      const raw = (err as { message?: string })?.message;
      let msg = 'Failed to send test email';
      try {
        if (raw) msg = JSON.parse(raw).error ?? msg;
      } catch {
        /* ignore */
      }
      toast.error(msg);
    } finally {
      setIsTesting(false);
    }
  };

  if (isLoading) return <p className="text-sm text-duck-dark/40">Loading...</p>;

  const showSmtpFields = provider === 'smtp' || provider === 'mailhog';

  return (
    <div className="grid gap-4">
      <Label className="grid gap-2">
        <span className="text-duck-dark/70 dark:text-foreground/70">Provider</span>
        <Select value={provider} onValueChange={(v) => handleProviderChange(v as Provider)}>
          <SelectTrigger className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground">
            <SelectValue />
          </SelectTrigger>
          <SelectContent className="z-[600]">
            <SelectItem value="mailhog">MailHog (local testing)</SelectItem>
            <SelectItem value="resend">Resend</SelectItem>
            <SelectItem value="smtp">Custom SMTP</SelectItem>
          </SelectContent>
        </Select>
      </Label>

      {provider === 'resend' && (
        <Label className="grid gap-2">
          <span className="text-duck-dark/70 dark:text-foreground/70">API Key</span>
          <Input
            type="password"
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
            placeholder="re_..."
            value={apiKey}
            onChange={(ev) => setApiKey(ev.target.value)}
          />
        </Label>
      )}

      {showSmtpFields && (
        <>
          <div className="grid grid-cols-[1fr_auto] gap-2">
            <Label className="grid gap-2">
              <span className="text-duck-dark/70 dark:text-foreground/70">Host</span>
              <Input
                className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
                placeholder="smtp.example.com"
                value={host}
                onChange={(ev) => setHost(ev.target.value)}
              />
            </Label>
            <Label className="grid gap-2">
              <span className="text-duck-dark/70 dark:text-foreground/70">Port</span>
              <Input
                type="number"
                className="h-11 w-24 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground"
                value={port}
                onChange={(ev) => setPort(ev.target.value)}
              />
            </Label>
          </div>
          {provider === 'smtp' && (
            <>
              <div className="grid grid-cols-2 gap-2">
                <Label className="grid gap-2">
                  <span className="text-duck-dark/70 dark:text-foreground/70">Username</span>
                  <Input
                    className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
                    placeholder="user@example.com"
                    value={username}
                    onChange={(ev) => setUsername(ev.target.value)}
                  />
                </Label>
                <Label className="grid gap-2">
                  <span className="text-duck-dark/70 dark:text-foreground/70">Password</span>
                  <Input
                    type="password"
                    className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground"
                    value={password}
                    onChange={(ev) => setPassword(ev.target.value)}
                  />
                </Label>
              </div>
              <Label className="flex items-center gap-3">
                <Switch checked={secure} onCheckedChange={setSecure} />
                <span className="text-duck-dark/70 dark:text-foreground/70">TLS / SSL</span>
              </Label>
            </>
          )}
        </>
      )}

      <div className="grid grid-cols-2 gap-2">
        <Label className="grid gap-2">
          <span className="text-duck-dark/70 dark:text-foreground/70">From Name</span>
          <Input
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
            value={fromName}
            onChange={(ev) => setFromName(ev.target.value)}
          />
        </Label>
        <Label className="grid gap-2">
          <span className="text-duck-dark/70 dark:text-foreground/70">From Email</span>
          <Input
            type="email"
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
            value={fromEmail}
            onChange={(ev) => setFromEmail(ev.target.value)}
          />
        </Label>
      </div>

      <div className="flex items-center gap-2">
        <Button
          type="button"
          onClick={handleSave}
          disabled={isSaving}
          className="flex-1 h-11 bg-duck-yellow hover:bg-duck-yellow/90 text-duck-teal font-bold transition-all duration-200 hover:scale-105 cursor-pointer disabled:opacity-50 disabled:hover:scale-100"
        >
          {isSaving ? 'Saving...' : 'Save'}
        </Button>
        <Button
          type="button"
          variant="outline"
          onClick={handleTestConnection}
          disabled={isTestingConnection}
          className="h-11 cursor-pointer disabled:opacity-50"
        >
          {isTestingConnection ? 'Testing...' : 'Test'}
        </Button>
      </div>

      <div className="border-t border-duck-dark/10 dark:border-foreground/10 pt-4 mt-1">
        <span className="text-sm font-medium text-duck-dark dark:text-foreground">Send Test Email</span>
        <div className="flex items-center gap-2 mt-2">
          <Input
            type="email"
            className="h-9 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40 flex-1"
            placeholder="recipient@example.com"
            value={testEmail}
            onChange={(ev) => setTestEmail(ev.target.value)}
            onKeyDown={(ev) => {
              if (ev.key === 'Enter') handleTest();
            }}
          />
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={handleTest}
            disabled={isTesting || !testEmail}
            className="h-9 cursor-pointer disabled:opacity-50"
          >
            {isTesting ? 'Sending...' : 'Send'}
          </Button>
        </div>
      </div>
    </div>
  );
};
