'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { localePath, type Locale } from '@ai-radar/shared';
import type { Dictionary } from '@/lib/dictionary';
import { login, register, getOAuthProviders, oauthUrl } from '@/lib/auth-client';

type Mode = 'signin' | 'register';
type State = 'idle' | 'working' | 'done' | 'error';

/**
 * Sign in and create account.
 *
 * One component for both, because they differ by two strings and one
 * endpoint — two near-identical forms would drift apart.
 *
 * Social buttons come first. Most people will use them, and putting the
 * password fields first implies the email path is the expected one.
 */
export function AuthForm({
  mode,
  locale,
  dict,
}: {
  mode: Mode;
  locale: Locale;
  dict: Dictionary;
}) {
  const t = dict.auth;
  const router = useRouter();

  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [state, setState] = useState<State>('idle');
  const [error, setError] = useState<string | null>(null);
  const [providers, setProviders] = useState<string[]>([]);

  // Only render buttons for providers that are actually configured — a
  // dead social button is worse than none.
  useEffect(() => {
    getOAuthProviders()
      .then((r) => setProviders(r.providers))
      .catch(() => setProviders([]));
  }, []);

  async function submit(event: React.FormEvent) {
    event.preventDefault();
    setState('working');
    setError(null);

    try {
      if (mode === 'register') {
        const result = await register({ email, password, locale });
        if (!result.ok) {
          setError(result.error ?? t.genericError);
          setState('error');
          return;
        }
        // Always "check your inbox", whether or not the address was
        // already registered — the API deliberately cannot tell us, and
        // showing anything else would leak it.
        setState('done');
        return;
      }

      const result = await login({ email, password });
      if (!result.ok) {
        setError(result.error ?? t.genericError);
        setState('error');
        return;
      }

      router.push(localePath('/account', locale));
      router.refresh();
    } catch {
      setError(t.genericError);
      setState('error');
    }
  }

  if (mode === 'register' && state === 'done') {
    return (
      <div className="auth-done">
        <p className="auth-done-title">{t.checkInbox}</p>
        <p className="t-body-sm">{t.checkInboxBody}</p>
      </div>
    );
  }

  return (
    <div className="auth-card">
      <h1 className="auth-title">{mode === 'signin' ? t.signInTitle : t.registerTitle}</h1>
      <p className="auth-blurb">{mode === 'signin' ? t.signInBlurb : t.registerBlurb}</p>

      {providers.length > 0 && (
        <>
          <div className="auth-providers">
            {providers.map((provider) => (
              <a key={provider} className="auth-provider" href={oauthUrl(provider)}>
                <ProviderMark provider={provider} />
                <span>
                  {t.continueWith} {providerLabel(provider)}
                </span>
              </a>
            ))}
          </div>
          <div className="auth-divider">
            <span>{t.or}</span>
          </div>
        </>
      )}

      <form onSubmit={submit} noValidate>
        <label className="auth-label" htmlFor="auth-email">
          {t.email}
        </label>
        <input
          id="auth-email"
          type="email"
          className="auth-input"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          autoComplete="email"
          required
          aria-invalid={state === 'error'}
        />

        <label className="auth-label" htmlFor="auth-password">
          {t.password}
        </label>
        <input
          id="auth-password"
          type="password"
          className="auth-input"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          autoComplete={mode === 'signin' ? 'current-password' : 'new-password'}
          required
          aria-invalid={state === 'error'}
        />

        {error && (
          <p className="auth-error" role="alert">
            {error}
          </p>
        )}

        <button
          type="submit"
          className="auth-submit"
          disabled={state === 'working' || email.length === 0 || password.length === 0}
        >
          {mode === 'signin' ? t.signIn : t.register}
        </button>
      </form>

      {mode === 'signin' && (
        <p className="auth-alt">
          <Link href={localePath('/reset', locale)}>{t.forgot}</Link>
        </p>
      )}

      <p className="auth-alt">
        {mode === 'signin' ? (
          <>
            {t.noAccount}{' '}
            <Link href={localePath('/register', locale)}>{t.register}</Link>
          </>
        ) : (
          <>
            {t.haveAccount} <Link href={localePath('/signin', locale)}>{t.signIn}</Link>
          </>
        )}
      </p>
    </div>
  );
}

function providerLabel(provider: string): string {
  return provider.charAt(0).toUpperCase() + provider.slice(1);
}

/** Simple marks. No icon library for three shapes. */
function ProviderMark({ provider }: { provider: string }) {
  if (provider === 'google') {
    return (
      <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
        <path
          fill="currentColor"
          d="M21.35 11.1h-9.17v2.98h5.27c-.23 1.37-1.6 4.02-5.27 4.02-3.17 0-5.76-2.62-5.76-5.86s2.59-5.86 5.76-5.86c1.8 0 3.01.77 3.7 1.43l2.52-2.43C16.78 3.87 14.66 3 12.18 3 7.03 3 2.86 7.17 2.86 12.32s4.17 9.32 9.32 9.32c5.38 0 8.95-3.78 8.95-9.11 0-.61-.07-1.08-.16-1.43z"
        />
      </svg>
    );
  }

  if (provider === 'github') {
    return (
      <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
        <path
          fill="currentColor"
          d="M12 2C6.48 2 2 6.48 2 12c0 4.42 2.87 8.17 6.84 9.5.5.09.68-.22.68-.48v-1.7c-2.78.6-3.37-1.34-3.37-1.34-.45-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.89 1.53 2.34 1.09 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.56-1.11-4.56-4.94 0-1.09.39-1.98 1.03-2.68-.1-.25-.45-1.27.1-2.65 0 0 .84-.27 2.75 1.02a9.6 9.6 0 015 0c1.91-1.29 2.75-1.02 2.75-1.02.55 1.38.2 2.4.1 2.65.64.7 1.03 1.59 1.03 2.68 0 3.84-2.34 4.69-4.57 4.94.36.31.68.92.68 1.85v2.74c0 .27.18.58.69.48A10 10 0 0022 12c0-5.52-4.48-10-10-10z"
        />
      </svg>
    );
  }

  return (
    <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
      <path
        fill="currentColor"
        d="M17.05 12.54c-.02-2.27 1.85-3.36 1.94-3.41-1.06-1.55-2.7-1.76-3.29-1.78-1.4-.14-2.73.82-3.44.82-.71 0-1.8-.8-2.96-.78-1.52.02-2.92.88-3.7 2.24-1.58 2.74-.4 6.8 1.13 9.02.75 1.09 1.64 2.31 2.81 2.27 1.13-.05 1.55-.73 2.92-.73 1.36 0 1.75.73 2.95.71 1.22-.02 1.99-1.11 2.73-2.2.86-1.26 1.22-2.48 1.24-2.55-.03-.01-2.38-.91-2.4-3.61zM14.9 5.6c.62-.75 1.04-1.8.93-2.84-.9.04-1.98.6-2.62 1.35-.58.66-1.08 1.72-.94 2.74 1 .08 2.02-.51 2.63-1.25z"
      />
    </svg>
  );
}
