import { useEffect, useRef } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { AlertTriangle, Check, Loader2, RefreshCw, ShieldCheck, X, Youtube } from "lucide-react";
import { api, type Me } from "../lib/api";
import { beginGrant, endOnboarding } from "../lib/onboarding";

// A first-login wizard that walks the user through granting YouTube access one scope at a
// time, each with a plain explanation and an up-front heads-up about Google's "unverified
// app" screen. Sign-in itself only asks for name/email (no warning); YouTube access is
// always an explicit, informed opt-in here.
//
// The visible step is derived from what's already granted, so the wizard resumes correctly
// after each redirect: no read -> "read", read but no write -> "write", both -> "done".
// Right after read is granted, it auto-imports the user's subscriptions so they land on a
// populated feed (channels already in the shared catalog appear instantly).

// A small reusable heads-up so the Google consent warning never feels like a surprise.
function ConsentHeadsUp() {
  return (
    <div className="flex gap-2.5 rounded-xl border border-amber-400/30 bg-amber-400/5 p-3 text-left">
      <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5 text-amber-400" />
      <p className="text-xs leading-relaxed text-fg/80">
        Google will show a <span className="font-medium">"Google hasn't verified this app"</span>{" "}
        screen — that's expected, because Siftlode hasn't gone through Google's full review.
        It's safe to continue: click <span className="font-medium">Advanced</span> →{" "}
        <span className="font-medium">Go to Siftlode</span>. You can revoke access anytime from
        your{" "}
        <a
          href="https://myaccount.google.com/permissions"
          target="_blank"
          rel="noreferrer"
          className="text-accent hover:underline"
        >
          Google Account
        </a>
        .
      </p>
    </div>
  );
}

function Dots({ index, total }: { index: number; total: number }) {
  return (
    <div className="flex justify-center gap-1.5">
      {Array.from({ length: total }).map((_, i) => (
        <span
          key={i}
          className={`h-1.5 rounded-full transition-all ${
            i === index ? "w-5 bg-accent" : "w-1.5 bg-border"
          }`}
        />
      ))}
    </div>
  );
}

export default function OnboardingWizard({ me, onClose }: { me: Me; onClose: () => void }) {
  const qc = useQueryClient();
  const importTriggered = useRef(false);

  // Once we have read access, find out whether any subscriptions are imported yet.
  const myStatus = useQuery({
    queryKey: ["my-status"],
    queryFn: api.myStatus,
    enabled: me.can_read,
  });

  const importSubs = useMutation({
    mutationFn: () => api.syncSubscriptions(),
    onSuccess: () => {
      // Feed/channels/status now have content — refresh the app behind the wizard.
      qc.invalidateQueries({ queryKey: ["feed"] });
      qc.invalidateQueries({ queryKey: ["feed-count"] });
      qc.invalidateQueries({ queryKey: ["channels"] });
      qc.invalidateQueries({ queryKey: ["my-status"] });
    },
  });

  // First time we see read access with zero imported channels, pull the user's
  // subscriptions automatically so they don't have to hunt for a button.
  useEffect(() => {
    if (
      me.can_read &&
      myStatus.data &&
      myStatus.data.channels_total === 0 &&
      !importTriggered.current
    ) {
      importTriggered.current = true;
      importSubs.mutate();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [me.can_read, myStatus.data?.channels_total]);

  // Closing without finishing the essential read step suppresses future auto-popups
  // (it stays reachable from Settings). Once read is granted, closing is just "done".
  const close = () => {
    endOnboarding(!me.can_read);
    onClose();
  };

  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if (e.key === "Escape") close();
    }
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [me.can_read]);

  // Are we currently importing (or about to)? Show a progress screen instead of the
  // "you're connected" step until the first import settles.
  const importing =
    me.can_read &&
    !importSubs.isError &&
    (importSubs.isPending ||
      (importTriggered.current && !importSubs.isSuccess) ||
      (myStatus.data?.channels_total === 0 && !importSubs.isSuccess));

  const step = !me.can_read ? "read" : !me.can_write ? "write" : "done";
  const stepIndex = step === "read" ? 0 : step === "write" ? 1 : 2;

  return (
    <div className="fixed inset-0 z-50 grid place-items-center p-4">
      <div className="absolute inset-0 bg-black/50 animate-[overlayIn_0.2s_ease]" onClick={close} />
      <div className="glass relative w-[min(94vw,460px)] rounded-2xl p-7 text-center animate-[panelIn_0.26s_cubic-bezier(0.22,1,0.36,1)]">
        <button
          onClick={close}
          className="absolute top-3 right-3 p-2 rounded-lg text-muted hover:text-fg hover:bg-card/60 transition"
          aria-label="Close"
        >
          <X className="w-4 h-4" />
        </button>

        {step === "read" && (
          <>
            <div className="mx-auto mb-4 grid place-items-center w-12 h-12 rounded-2xl bg-accent/15 text-accent">
              <Youtube className="w-6 h-6" />
            </div>
            <h2 className="text-lg font-semibold">Connect your YouTube subscriptions</h2>
            <p className="text-sm text-muted leading-relaxed mt-2 mb-4">
              You're signed in. To build your feed, Siftlode needs{" "}
              <span className="text-fg/90">read-only</span> access to the channels you're
              subscribed to on YouTube. It never posts, deletes, or changes anything with this.
            </p>
            <ConsentHeadsUp />
            <div className="mt-5 flex flex-col gap-2">
              <button
                onClick={() => beginGrant("read")}
                className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-xl font-semibold bg-accent text-accent-fg hover:opacity-90 transition"
              >
                <Youtube className="w-4 h-4" /> Connect (read-only)
              </button>
              <button
                onClick={close}
                className="px-5 py-2 rounded-xl text-sm text-muted hover:text-fg transition"
              >
                Skip for now
              </button>
            </div>
          </>
        )}

        {/* Read granted: show import progress before the optional write step. */}
        {me.can_read && importing && (
          <>
            <div className="mx-auto mb-4 grid place-items-center w-12 h-12 rounded-2xl bg-accent/15 text-accent">
              <Loader2 className="w-6 h-6 animate-spin" />
            </div>
            <h2 className="text-lg font-semibold">Building your feed…</h2>
            <p className="text-sm text-muted leading-relaxed mt-2 mb-2">
              Importing your YouTube subscriptions. Channels already in Siftlode show up
              instantly; any new ones fill in automatically in the background.
            </p>
          </>
        )}

        {step === "write" && !importing && (
          <>
            <div className="mx-auto mb-4 grid place-items-center w-12 h-12 rounded-2xl bg-accent/15 text-accent">
              <Check className="w-6 h-6" />
            </div>
            <h2 className="text-lg font-semibold">You're connected</h2>
            <p className="text-sm text-muted leading-relaxed mt-2 mb-4">
              {importSubs.isError ? (
                <>Your YouTube account is connected, but importing subscriptions failed — you
                can retry from Settings → Sync. </>
              ) : (
                <>
                  Your feed is ready
                  {myStatus.data ? ` (${myStatus.data.channels_total} channels)` : ""}. Optionally,
                  let Siftlode{" "}
                </>
              )}
              {!importSubs.isError && (
                <>
                  <span className="text-fg/90">unsubscribe</span> from channels on YouTube for you
                  — this needs an extra write permission. Skip it to stay read-only; you can
                  always enable it later in Settings.
                </>
              )}
            </p>
            {importSubs.isError && (
              <button
                onClick={() => importSubs.mutate()}
                className="mb-3 inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl text-sm bg-card border border-border hover:border-accent transition"
              >
                <RefreshCw className="w-4 h-4" /> Retry import
              </button>
            )}
            <ConsentHeadsUp />
            <div className="mt-5 flex flex-col gap-2">
              <button
                onClick={() => beginGrant("write")}
                className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-xl font-semibold bg-accent text-accent-fg hover:opacity-90 transition"
              >
                <ShieldCheck className="w-4 h-4" /> Enable unsubscribe
              </button>
              <button
                onClick={() => {
                  endOnboarding(false);
                  onClose();
                }}
                className="px-5 py-2 rounded-xl text-sm text-muted hover:text-fg transition"
              >
                No thanks — keep it read-only
              </button>
            </div>
          </>
        )}

        {step === "done" && !importing && (
          <>
            <div className="mx-auto mb-4 grid place-items-center w-12 h-12 rounded-2xl bg-accent/15 text-accent">
              <Check className="w-6 h-6" />
            </div>
            <h2 className="text-lg font-semibold">All set</h2>
            <p className="text-sm text-muted leading-relaxed mt-2 mb-5">
              Read and unsubscribe access are both granted. You can review or revoke either one
              anytime in Settings → Account, or from your Google Account.
            </p>
            <button
              onClick={() => {
                endOnboarding(false);
                onClose();
              }}
              className="inline-flex items-center justify-center gap-2 px-5 py-3 rounded-xl font-semibold bg-accent text-accent-fg hover:opacity-90 transition w-full"
            >
              Done
            </button>
          </>
        )}

        <div className="mt-6">
          <Dots index={stepIndex} total={3} />
        </div>
      </div>
    </div>
  );
}
