import { ConvexAuthProvider, useAuthActions } from "@convex-dev/auth/react";
import {
  Authenticated,
  AuthLoading,
  ConvexReactClient,
  Unauthenticated,
  useQuery,
} from "convex/react";
import { makeFunctionReference } from "convex/server";
import React, { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { createRoot } from "react-dom/client";
import "./auth-widget.css";

const deploymentUrl = import.meta.env.VITE_CONVEX_URL;
const myProfileRef = makeFunctionReference("customers:myProfile");

function AccountGreeting() {
  const profile = useQuery(myProfileRef, {});
  const name = profile?.displayName?.trim();
  return <p>Hello, {name || "there"}!</p>;
}

function AccountWidget() {
  const { signIn, signOut } = useAuthActions();
  const [isOpen, setIsOpen] = useState(false);
  const [mode, setMode] = useState("signIn");
  const [status, setStatus] = useState("");
  const [busy, setBusy] = useState(false);
  const dialog = useRef(null);

  useEffect(() => {
    if (!isOpen) return;
    const onKeyDown = (event) => event.key === "Escape" && setIsOpen(false);
    document.addEventListener("keydown", onKeyDown);
    dialog.current?.querySelector("input")?.focus();
    return () => document.removeEventListener("keydown", onKeyDown);
  }, [isOpen, mode]);

  async function submit(event) {
    event.preventDefault();
    setBusy(true);
    setStatus("");
    try {
      const formData = new FormData(event.currentTarget);
      formData.set("flow", mode);
      await signIn("password", formData);
      setIsOpen(false);
      event.currentTarget.reset();
    } catch {
      setStatus(
        mode === "signIn"
          ? "We couldn't sign you in. Check your details and try again."
          : "We couldn't create the account. Check the password rules and try again.",
      );
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="to-account">
      <AuthLoading>
        <span className="to-account-loading">Checking…</span>
      </AuthLoading>
      <Unauthenticated>
        <button
          className="to-account-trigger"
          type="button"
          onClick={() => setIsOpen(true)}
        >
          Log in / Sign up
        </button>
      </Unauthenticated>
      <Authenticated>
        <div className="to-account-signed-in">
          <button
            className="to-account-trigger"
            type="button"
            aria-haspopup="menu"
            onClick={(event) => event.currentTarget.blur()}
          >
            Account
          </button>
          <div className="to-account-menu">
            <AccountGreeting />
            <a href="account.html">My account</a>
            <button type="button" onClick={() => void signOut()}>
              Log out
            </button>
          </div>
        </div>
      </Authenticated>

      <Unauthenticated>
        {isOpen &&
          createPortal(
            <div
              className="to-auth-backdrop"
              onMouseDown={(event) =>
                event.target === event.currentTarget && setIsOpen(false)
              }
            >
              <section
                ref={dialog}
                className="to-auth-dialog"
                role="dialog"
                aria-modal="true"
                aria-labelledby="to-auth-title"
              >
                <button
                  className="to-auth-close"
                  type="button"
                  aria-label="Close"
                  onClick={() => setIsOpen(false)}
                >
                  ×
                </button>
                <h2 id="to-auth-title">
                  {mode === "signIn" ? "Welcome back!" : "Create an account"}
                </h2>
                <form onSubmit={submit}>
                  <label>
                    <span>Email *</span>
                    <input
                      required
                      autoComplete="email"
                      name="email"
                      type="email"
                      placeholder="Enter your email"
                    />
                  </label>
                  <label>
                    <span>Password *</span>
                    <input
                      required
                      minLength="12"
                      autoComplete={
                        mode === "signIn" ? "current-password" : "new-password"
                      }
                      name="password"
                      type="password"
                      placeholder={
                        mode === "signIn"
                          ? "Enter your password"
                          : "Create your password"
                      }
                    />
                  </label>
                  {mode === "signUp" && (
                    <p className="to-auth-rule">
                      12+ characters with uppercase, lowercase, a number, and a
                      symbol.
                    </p>
                  )}
                  {status && (
                    <p className="to-auth-error" role="alert">
                      {status}
                    </p>
                  )}
                  <button
                    className="to-auth-submit"
                    disabled={busy}
                    type="submit"
                  >
                    {busy
                      ? "Please wait…"
                      : mode === "signIn"
                        ? "Log in"
                        : "Create account"}
                  </button>
                  {mode === "signIn" && (
                    <button
                      className="to-auth-recover"
                      type="button"
                      onClick={() =>
                        setStatus(
                          "Password recovery will be available once the store email service is connected.",
                        )
                      }
                    >
                      Forgot your password
                    </button>
                  )}
                </form>
                <div className="to-auth-switch-row">
                  <span>
                    {mode === "signIn"
                      ? "Don’t have an account yet?"
                      : "Already have an account?"}
                  </span>
                  <button
                    className="to-auth-switch"
                    type="button"
                    onClick={() => {
                      setMode(mode === "signIn" ? "signUp" : "signIn");
                      setStatus("");
                    }}
                  >
                    {mode === "signIn" ? "Create an account" : "Log in"}
                  </button>
                </div>
              </section>
            </div>,
            document.body,
          )}
      </Unauthenticated>
    </div>
  );
}

const root = document.getElementById("account-root");
if (root) {
  if (!deploymentUrl) {
    root.innerHTML =
      '<button class="to-account-trigger" type="button" title="Connect Convex to activate customer accounts">Log in / Sign up</button>';
  } else {
    const client = new ConvexReactClient(deploymentUrl);
    createRoot(root).render(
      <React.StrictMode>
        <ConvexAuthProvider client={client}>
          <AccountWidget />
        </ConvexAuthProvider>
      </React.StrictMode>,
    );
  }
}
