"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { signIn, getSession } from "next-auth/react";
import BrandLogo from "@/components/brand-logo";

type OAuthProvider = "google" | "facebook" | "apple";

function GoogleIcon() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <path
        d="M21.6 12.2c0-.7-.06-1.2-.18-1.8H12v3.4h5.4a4.6 4.6 0 0 1-2 3v2.5h3.2c1.9-1.7 3-4.3 3-7.1Z"
        fill="#4285F4"
      />
      <path
        d="M12 22c2.7 0 5-.9 6.6-2.4l-3.2-2.5c-.9.6-2 .95-3.4.95-2.6 0-4.8-1.75-5.6-4.1H3.1v2.6A10 10 0 0 0 12 22Z"
        fill="#34A853"
      />
      <path
        d="M6.4 13.95a6 6 0 0 1 0-3.9V7.45H3.1a10 10 0 0 0 0 9.1l3.3-2.6Z"
        fill="#FBBC05"
      />
      <path
        d="M12 5.95c1.5 0 2.8.5 3.8 1.5l2.85-2.85A10 10 0 0 0 12 2a10 10 0 0 0-8.9 5.45l3.3 2.6C7.2 7.7 9.4 5.95 12 5.95Z"
        fill="#EA4335"
      />
    </svg>
  );
}

function FacebookIcon() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <path
        d="M22 12a10 10 0 1 0-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.5 1.49-3.89 3.78-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.78l-.44 2.89h-2.34v6.99A10 10 0 0 0 22 12Z"
        fill="#1877F2"
      />
    </svg>
  );
}

function AppleIcon() {
  return (
    <svg viewBox="0 0 24 24" className="h-5 w-5" aria-hidden="true">
      <path
        d="M16.36 12.78c-.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.93.88-3.71 2.24-1.58 2.74-.4 6.8 1.13 9.02.75 1.09 1.65 2.31 2.82 2.27 1.13-.05 1.56-.73 2.93-.73 1.37 0 1.75.73 2.95.71 1.22-.02 1.99-1.11 2.74-2.2.86-1.26 1.22-2.48 1.24-2.55-.03-.01-2.38-.91-2.4-3.63ZM14.1 6.02c.62-.76 1.04-1.8.93-2.85-.9.04-1.98.6-2.62 1.35-.57.67-1.08 1.74-.94 2.76.99.08 2.01-.5 2.63-1.26Z"
        fill="currentColor"
      />
    </svg>
  );
}

const SOCIAL: { provider: OAuthProvider; label: string; icon: React.ReactNode }[] = [
  { provider: "google", label: "Continue with Google", icon: <GoogleIcon /> },
  { provider: "facebook", label: "Continue with Facebook", icon: <FacebookIcon /> },
  { provider: "apple", label: "Continue with Apple", icon: <AppleIcon /> },
];

// Credentials and phone-otp branch by role below (matching the Supabase
// original's redirectByRole()) since we get a client-side result back to
// check before navigating. OAuth can't: Auth.js's callbackUrl is fixed
// before the provider round-trip starts, so all 3 social providers land
// admins and organizers on /dashboard alike -- a known simplification,
// harmless since dashboard/layout.tsx admits admins too (see its comment).
const DEFAULT_POST_LOGIN_DEST = "/dashboard";

async function destinationByRole(): Promise<string> {
  const session = await getSession();
  return session?.user?.role === "admin" ? "/admin" : "/dashboard";
}

export default function LoginPage() {
  const router = useRouter();

  const [method, setMethod] = useState<"email" | "phone">("email");
  const [mode, setMode] = useState<"sign-in" | "sign-up">("sign-in");

  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [awaitingEmailVerification, setAwaitingEmailVerification] = useState(false);
  const [verificationCode, setVerificationCode] = useState("");

  const [phone, setPhone] = useState("");
  const [otp, setOtp] = useState("");
  const [otpSent, setOtpSent] = useState(false);

  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  // Surface failures bounced back from the OAuth callback route.
  useEffect(() => {
    if (new URLSearchParams(window.location.search).get("error")) {
      // eslint-disable-next-line react-hooks/set-state-in-effect -- one-time read of the post-redirect URL after mount; deferring avoids a hydration mismatch on this static page
      setError("Social sign-in failed. Please try again.");
    }
  }, []);

  async function signInWithProvider(provider: OAuthProvider) {
    setError(null);
    setLoading(true);
    // Auth.js handles the full redirect dance itself; this only returns if
    // something fails before the provider redirect even happens.
    await signIn(provider, { callbackUrl: DEFAULT_POST_LOGIN_DEST });
    setLoading(false);
  }

  async function handleEmailSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setInfo(null);
    setLoading(true);

    if (mode === "sign-up") {
      const res = await fetch("/api/auth/register", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password, name: name || undefined }),
      });
      const data = await res.json();
      if (!res.ok) {
        setError(data.error ?? "Could not create account.");
        setLoading(false);
        return;
      }
      // Account created but not yet verified -- a code was just emailed.
      // Switch to the code-entry step instead of signing in immediately.
      setAwaitingEmailVerification(true);
      setInfo(`We sent a 6-digit code to ${email}.`);
      setLoading(false);
      return;
    }

    const result = await signIn("credentials", { email, password, redirect: false });
    if (result?.error) {
      setError("Incorrect email or password.");
      setLoading(false);
      return;
    }
    router.push(await destinationByRole());
    router.refresh();
  }

  async function handleVerifyEmailCode(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setLoading(true);

    const res = await fetch("/api/auth/verify-email/confirm", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, code: verificationCode }),
    });
    const data = await res.json();
    if (!res.ok) {
      setError(data.error ?? "That code didn't work. Check it and try again.");
      setLoading(false);
      return;
    }

    const result = await signIn("credentials", { email, password, redirect: false });
    if (result?.error) {
      setError("Verified, but sign-in failed -- try signing in again.");
      setLoading(false);
      return;
    }
    router.push(await destinationByRole());
    router.refresh();
  }

  async function handleResendEmailCode() {
    setError(null);
    setInfo(null);
    setLoading(true);

    const res = await fetch("/api/auth/verify-email/request", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email }),
    });
    const data = await res.json();
    setLoading(false);
    if (!res.ok) {
      setError(data.error ?? "Could not resend code.");
      return;
    }
    setInfo(`We sent a new code to ${email}.`);
  }

  async function handleSendOtp(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setInfo(null);
    setLoading(true);

    const res = await fetch("/api/auth/otp/request", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ phone }),
    });
    const data = await res.json();
    if (!res.ok) {
      setError(data.error ?? "Could not send code.");
      setLoading(false);
      return;
    }

    setOtpSent(true);
    setInfo(`We sent a 6-digit code to ${phone}.`);
    setLoading(false);
  }

  async function handleVerifyOtp(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setLoading(true);

    const result = await signIn("phone-otp", { phone, code: otp, redirect: false });
    if (result?.error) {
      setError("That code didn't work. Check it and try again.");
      setLoading(false);
      return;
    }

    router.push(await destinationByRole());
    router.refresh();
  }

  function switchMethod(next: "email" | "phone") {
    setMethod(next);
    setError(null);
    setInfo(null);
    setOtpSent(false);
    setOtp("");
    setAwaitingEmailVerification(false);
    setVerificationCode("");
  }

  return (
    <div className="min-h-screen flex flex-col items-center justify-center bg-bg px-4 py-12">
      <Link href="/" className="mb-8 inline-flex" aria-label="VibePass Tickets — home">
        <BrandLogo size="md" showTagline />
      </Link>

      <div className="w-full max-w-sm rounded-2xl border border-line bg-panel p-8 shadow-2xl shadow-black/40">
        <h1 className="text-xl font-semibold text-ink mb-1">Organizer sign in</h1>
        <p className="text-sm text-muted mb-6">Manage your events and ticket sales.</p>

        {/* Social sign-in */}
        <div className="space-y-2">
          {SOCIAL.map((s) => (
            <button
              key={s.provider}
              type="button"
              onClick={() => signInWithProvider(s.provider)}
              disabled={loading}
              className="flex w-full items-center justify-center gap-3 rounded-md border border-line bg-panel-soft px-4 py-2 text-sm font-medium text-ink hover:border-white/30 disabled:opacity-50"
            >
              {s.icon}
              {s.label}
            </button>
          ))}
        </div>

        <div className="my-6 flex items-center gap-3">
          <span className="h-px flex-1 bg-line" />
          <span className="text-xs uppercase tracking-wide text-muted">or</span>
          <span className="h-px flex-1 bg-line" />
        </div>

        {/* Email / phone toggle */}
        <div className="mb-4 flex rounded-md border border-line p-1 text-sm">
          {(["email", "phone"] as const).map((m) => (
            <button
              key={m}
              type="button"
              onClick={() => switchMethod(m)}
              className={`flex-1 rounded px-3 py-1.5 font-medium capitalize transition-colors ${
                method === m ? "bg-brand-green text-white" : "text-muted hover:text-ink"
              }`}
            >
              {m}
            </button>
          ))}
        </div>

        {method === "email" && awaitingEmailVerification ? (
          <form onSubmit={handleVerifyEmailCode} className="space-y-4">
            <div>
              <label className="block text-sm font-medium text-ink mb-1">Verification code</label>
              <input
                type="text"
                inputMode="numeric"
                required
                placeholder="123456"
                value={verificationCode}
                onChange={(e) => setVerificationCode(e.target.value)}
                className="input tracking-widest"
              />
            </div>

            {info && <p className="text-sm text-emerald-400">{info}</p>}
            {error && <p className="text-sm text-red-400">{error}</p>}

            <button
              type="submit"
              disabled={loading}
              className="w-full rounded-md bg-brand-green text-white py-2 text-sm font-semibold hover:bg-brand-green-h disabled:opacity-50"
            >
              {loading ? "Please wait…" : "Verify & continue"}
            </button>

            <button
              type="button"
              onClick={handleResendEmailCode}
              disabled={loading}
              className="text-sm text-brand-green-h hover:underline"
            >
              Resend code
            </button>
          </form>
        ) : method === "email" ? (
          <form onSubmit={handleEmailSubmit} className="space-y-4">
            {mode === "sign-up" && (
              <div>
                <label className="block text-sm font-medium text-ink mb-1">Name</label>
                <input
                  type="text"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  className="input"
                />
              </div>
            )}
            <div>
              <label className="block text-sm font-medium text-ink mb-1">Email</label>
              <input
                type="email"
                required
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                className="input"
              />
            </div>
            <div>
              <div className="flex items-baseline justify-between mb-1">
                <label className="block text-sm font-medium text-ink">Password</label>
                {mode === "sign-in" && (
                  <Link href="/forgot-password" className="text-xs text-brand-green-h hover:underline">
                    Forgot password?
                  </Link>
                )}
              </div>
              <input
                type="password"
                required
                minLength={8}
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className="input"
              />
            </div>

            {info && <p className="text-sm text-emerald-400">{info}</p>}
            {error && <p className="text-sm text-red-400">{error}</p>}

            <button
              type="submit"
              disabled={loading}
              className="w-full rounded-md bg-brand-green text-white py-2 text-sm font-semibold hover:bg-brand-green-h disabled:opacity-50"
            >
              {loading ? "Please wait…" : mode === "sign-in" ? "Sign in" : "Create account"}
            </button>

            <button
              type="button"
              onClick={() => setMode(mode === "sign-in" ? "sign-up" : "sign-in")}
              className="text-sm text-brand-green-h hover:underline"
            >
              {mode === "sign-in" ? "Need an account? Sign up" : "Have an account? Sign in"}
            </button>
          </form>
        ) : (
          <form onSubmit={otpSent ? handleVerifyOtp : handleSendOtp} className="space-y-4">
            <div>
              <label className="block text-sm font-medium text-ink mb-1">Phone number</label>
              <input
                type="tel"
                required
                placeholder="+254712345678"
                value={phone}
                onChange={(e) => setPhone(e.target.value)}
                disabled={otpSent}
                className="input disabled:opacity-60"
              />
            </div>

            {otpSent && (
              <div>
                <label className="block text-sm font-medium text-ink mb-1">
                  Verification code
                </label>
                <input
                  type="text"
                  inputMode="numeric"
                  required
                  placeholder="123456"
                  value={otp}
                  onChange={(e) => setOtp(e.target.value)}
                  className="input tracking-widest"
                />
              </div>
            )}

            {info && <p className="text-sm text-muted">{info}</p>}
            {error && <p className="text-sm text-red-400">{error}</p>}

            <button
              type="submit"
              disabled={loading}
              className="w-full rounded-md bg-brand-green text-white py-2 text-sm font-semibold hover:bg-brand-green-h disabled:opacity-50"
            >
              {loading
                ? "Please wait…"
                : otpSent
                  ? "Verify & continue"
                  : "Send code"}
            </button>

            {otpSent && (
              <button
                type="button"
                onClick={() => {
                  setOtpSent(false);
                  setOtp("");
                  setInfo(null);
                  setError(null);
                }}
                className="text-sm text-brand-green-h hover:underline"
              >
                Use a different number
              </button>
            )}
          </form>
        )}
      </div>
    </div>
  );
}
