import { useEffect, useState, type FormEvent, type ReactNode } from 'react';
import {
  GoogleAuthProvider,
  isSignInWithEmailLink,
  sendSignInLinkToEmail,
  signInWithEmailLink,
  signInWithPopup,
} from 'firebase/auth';
import { getFirebaseAuth } from '../../lib/firebase/client';

type Props = {
  locale: 'ar' | 'en';
  redirectTo: string;
};

const EMAIL_STORAGE_KEY = 'emailForSignIn';

const copy = {
  ar: {
    email: 'البريد الإلكتروني',
    sendLink: 'إرسال رابط الدخول',
    sending: 'جاري الإرسال…',
    google: 'المتابعة مع Google',
    error: 'تعذر إرسال الرابط. تحقق من البريد الإلكتروني وحاول مرة أخرى.',
    verifyError: 'رابط الدخول غير صالح أو منتهي الصلاحية. اطلب رابطاً جديداً.',
    notAuthorized: 'هذا الحساب غير مصرح له بالوصول إلى لوحة الإدارة.',
    secureNote: 'اتصال آمن ومشفر',
    sentTitle: 'تحقق من بريدك الإلكتروني',
    sentBody: (email: string) =>
      `أرسلنا رابط تسجيل دخول إلى ${email}. افتح الرابط من هذا الجهاز لتسجيل الدخول.`,
    useAnotherEmail: 'استخدام بريد إلكتروني آخر',
    verifying: 'جاري التحقق من رابط الدخول…',
    confirmEmailTitle: 'أكّد بريدك الإلكتروني',
    confirmEmailBody: 'لإتمام تسجيل الدخول، يرجى إدخال البريد الإلكتروني الذي استخدمته لطلب الرابط.',
    confirmButton: 'تأكيد وتسجيل الدخول',
  },
  en: {
    email: 'Email address',
    sendLink: 'Send sign-in link',
    sending: 'Sending…',
    google: 'Continue with Google',
    error: 'Could not send the link. Check the email address and try again.',
    verifyError: 'This sign-in link is invalid or has expired. Request a new one.',
    notAuthorized: 'This account is not authorized to access the admin panel.',
    secureNote: 'Secure encrypted connection',
    sentTitle: 'Check your email',
    sentBody: (email: string) => `We sent a sign-in link to ${email}. Open it on this device to sign in.`,
    useAnotherEmail: 'Use a different email',
    verifying: 'Verifying sign-in link…',
    confirmEmailTitle: 'Confirm your email',
    confirmEmailBody: 'To finish signing in, enter the email address you used to request the link.',
    confirmButton: 'Confirm and sign in',
  },
} as const;

async function createServerSession(idToken: string) {
  const response = await fetch('/api/auth/session', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ idToken }),
  });

  if (response.status === 403) {
    const body = await response.json().catch(() => ({}));
    if (body?.error === 'not-authorized') {
      throw new Error('not-authorized');
    }
  }

  if (!response.ok) {
    throw new Error('Failed to create session');
  }
}

function GoogleIcon() {
  return (
    <svg className="h-5 w-5 shrink-0" viewBox="0 0 24 24" aria-hidden="true">
      <path
        fill="#4285F4"
        d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
      />
      <path
        fill="#34A853"
        d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
      />
      <path
        fill="#FBBC05"
        d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
      />
      <path
        fill="#EA4335"
        d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
      />
    </svg>
  );
}

function MailIcon() {
  return (
    <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.75"
        d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
      />
    </svg>
  );
}

function Spinner() {
  return (
    <span
      className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"
      aria-hidden="true"
    />
  );
}

function SpinnerLabel({ label }: { label: string }) {
  return (
    <span className="inline-flex items-center gap-2">
      <Spinner />
      {label}
    </span>
  );
}

export default function LoginForm({ locale, redirectTo }: Props) {
  const ui = copy[locale];
  const [email, setEmail] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [linkSentTo, setLinkSentTo] = useState<string | null>(null);
  const [needsEmailConfirmation, setNeedsEmailConfirmation] = useState(false);
  const [verifying, setVerifying] = useState(false);

  async function finishSignIn(idToken: string) {
    await createServerSession(idToken);
    window.location.href = redirectTo;
  }

  useEffect(() => {
    const auth = getFirebaseAuth();
    if (!isSignInWithEmailLink(auth, window.location.href)) return;

    const storedEmail = window.localStorage.getItem(EMAIL_STORAGE_KEY);
    if (!storedEmail) {
      setNeedsEmailConfirmation(true);
      return;
    }

    setVerifying(true);
    signInWithEmailLink(auth, storedEmail, window.location.href)
      .then(async (credential) => {
        window.localStorage.removeItem(EMAIL_STORAGE_KEY);
        const idToken = await credential.user.getIdToken();
        await finishSignIn(idToken);
      })
      .catch((err: unknown) => {
        window.localStorage.removeItem(EMAIL_STORAGE_KEY);
        setVerifying(false);
        setError(err instanceof Error && err.message === 'not-authorized' ? ui.notAuthorized : ui.verifyError);
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  async function handleSendLink(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setLoading(true);
    setError(null);

    try {
      const auth = getFirebaseAuth();
      await sendSignInLinkToEmail(auth, email, {
        url: window.location.href,
        handleCodeInApp: true,
      });
      window.localStorage.setItem(EMAIL_STORAGE_KEY, email);
      setLinkSentTo(email);
    } catch {
      setError(ui.error);
    } finally {
      setLoading(false);
    }
  }

  async function handleConfirmEmail(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setLoading(true);
    setError(null);

    try {
      const auth = getFirebaseAuth();
      const credential = await signInWithEmailLink(auth, email, window.location.href);
      const idToken = await credential.user.getIdToken();
      await finishSignIn(idToken);
    } catch (err: unknown) {
      setError(err instanceof Error && err.message === 'not-authorized' ? ui.notAuthorized : ui.verifyError);
      setLoading(false);
    }
  }

  async function handleGoogleSignIn() {
    setLoading(true);
    setError(null);

    try {
      const auth = getFirebaseAuth();
      const credential = await signInWithPopup(auth, new GoogleAuthProvider());
      const idToken = await credential.user.getIdToken();
      await finishSignIn(idToken);
    } catch (err: unknown) {
      setError(err instanceof Error && err.message === 'not-authorized' ? ui.notAuthorized : ui.error);
      setLoading(false);
    }
  }

  const inputClass =
    'input w-full border-base-300 bg-base-100 ps-11 focus:border-primary focus:outline-none';

  const errorBlock: ReactNode = error ? (
    <div className="rounded-xl border border-error/20 bg-error/5 px-4 py-3 text-sm text-error" role="alert">
      {error}
    </div>
  ) : null;

  const emailField = (
    <label className="form-control w-full">
      <span className="label-text mb-2 font-medium text-base-content/80">{ui.email}</span>
      <div className="relative">
        <span className="pointer-events-none absolute inset-y-0 inset-s-0 flex items-center ps-3.5 text-base-content/35">
          <svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth="1.75"
              d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
            />
          </svg>
        </span>
        <input
          type="email"
          className={inputClass}
          value={email}
          onChange={(event) => setEmail(event.target.value)}
          autoComplete="email"
          placeholder={locale === 'ar' ? 'name@example.com' : 'you@company.com'}
          required
          disabled={loading}
        />
      </div>
    </label>
  );

  if (verifying) {
    return (
      <div className="flex flex-col items-center justify-center gap-3 py-10 text-center">
        <Spinner />
        <p className="text-sm text-base-content/60">{ui.verifying}</p>
      </div>
    );
  }

  if (needsEmailConfirmation) {
    return (
      <div className="space-y-6">
        <div className="space-y-2">
          <h3 className="text-lg font-semibold text-base-content">{ui.confirmEmailTitle}</h3>
          <p className="text-sm text-base-content/60">{ui.confirmEmailBody}</p>
        </div>
        <form onSubmit={handleConfirmEmail} className="space-y-4">
          {emailField}
          {errorBlock}
          <button
            type="submit"
            className="btn btn-primary h-12 w-full text-base font-semibold"
            disabled={loading}
          >
            {loading ? <SpinnerLabel label={ui.sending} /> : ui.confirmButton}
          </button>
        </form>
      </div>
    );
  }

  if (linkSentTo) {
    return (
      <div className="space-y-6 text-center">
        <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-primary/10 text-primary">
          <MailIcon />
        </div>
        <div className="space-y-2">
          <h3 className="text-lg font-semibold text-base-content">{ui.sentTitle}</h3>
          <p className="text-sm leading-relaxed text-base-content/60">{ui.sentBody(linkSentTo)}</p>
        </div>
        <button
          type="button"
          className="btn btn-ghost btn-sm"
          onClick={() => {
            setLinkSentTo(null);
            setEmail('');
          }}
        >
          {ui.useAnotherEmail}
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <form onSubmit={handleSendLink} className="space-y-4">
        {emailField}
        {errorBlock}

        <button
          type="submit"
          className="btn btn-primary mt-2 h-12 w-full text-base font-semibold"
          disabled={loading}
        >
          {loading ? <SpinnerLabel label={ui.sending} /> : ui.sendLink}
        </button>
      </form>

      <div className="relative">
        <div className="absolute inset-0 flex items-center" aria-hidden="true">
          <div className="w-full border-t border-base-300"></div>
        </div>
        <div className="relative flex justify-center">
          <span className="bg-base-100 px-3 text-xs font-medium uppercase tracking-wider text-base-content/45">
            {locale === 'ar' ? 'أو' : 'or'}
          </span>
        </div>
      </div>

      <button
        type="button"
        className="btn h-12 w-full border-base-300 bg-base-100 text-base-content hover:border-base-content/20 hover:bg-base-200"
        onClick={handleGoogleSignIn}
        disabled={loading}
      >
        <GoogleIcon />
        {ui.google}
      </button>

      <p className="flex items-center justify-center gap-2 text-center text-xs text-base-content/45">
        <svg className="h-4 w-4 shrink-0 text-success" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
        </svg>
        {ui.secureNote}
      </p>
    </div>
  );
}
