"use client";

import { useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Home, Megaphone, Wallet, Settings, LogOut, PanelLeftClose, PanelLeftOpen, Menu, X } from "lucide-react";
import { api, auth } from "@/lib/api";
import { readBrand, writeBrand, applyBrandVars, DEFAULT_BRAND, type Brand } from "@/lib/brand";
import { cn } from "./cn";
import { Button, Input, FormField } from "./ui";

const NAV = [
  { href: "/dashboard", label: "Home", icon: Home, exact: true },
  { href: "/dashboard/marketing", label: "Marketing", icon: Megaphone },
  { href: "/dashboard/payments", label: "Payments", icon: Wallet },
  { href: "/dashboard/settings", label: "Settings", icon: Settings },
];

export function PortalShell({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  const [me, setMe] = useState<{ id: string; name: string } | null | undefined>(undefined);
  const [collapsed, setCollapsed] = useState(false);
  const [drawer, setDrawer] = useState(false);
  const [brand, setBrand] = useState<Brand>(DEFAULT_BRAND);

  useEffect(() => {
    setMe(auth.get());
    const cached = readBrand();
    if (cached.name || cached.logoUrl) setBrand(cached);
    applyBrandVars(cached);
    // Affiliates hold an affiliate token, not a Shopify session token, so the
    // /admin/* branding routes 401 for them — use the public config instead.
    api.get("/affiliates/signup-config").then((c) => {
      const b = c?.branding ?? {};
      const next: Brand = {
        logoUrl: b.logoUrl ?? DEFAULT_BRAND.logoUrl,
        name: c?.programName || DEFAULT_BRAND.name,
        brandColor: b.brandColor ?? null,
        brandSecondaryColor: b.brandSecondaryColor ?? null,
      };
      setBrand(next);
      writeBrand(next);
      applyBrandVars(next);
    }).catch(() => {/* keep the built-in brand */});
  }, []);

  if (me === undefined) {
    return <div className="fixed inset-0 flex items-center justify-center text-sm text-gray-400">Loading…</div>;
  }
  if (!me) return <LoginGate onLogin={setMe} brand={brand} />;

  const active = (href: string, exact?: boolean) => (exact ? pathname === href : pathname === href || pathname.startsWith(href + "/"));

  const NavLinks = ({ collapsed }: { collapsed: boolean }) => (
    <nav className="flex-1 space-y-1 px-2 py-3">
      {NAV.map(({ href, label, icon: Icon, exact }) => {
        const on = active(href, exact);
        return (
          <Link
            key={href}
            href={href}
            title={collapsed ? label : undefined}
            onClick={() => setDrawer(false)}
            className={cn(
              "flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
              on ? "bg-[var(--brand)] text-white shadow-sm" : "text-gray-600 hover:bg-gray-100",
              collapsed && "justify-center px-0",
            )}
          >
            <Icon className={cn("h-[18px] w-[18px] shrink-0", on ? "text-white" : "text-gray-400")} />
            {!collapsed && <span className="truncate">{label}</span>}
          </Link>
        );
      })}
    </nav>
  );

  const Brand = ({ collapsed }: { collapsed: boolean }) => (
    <div className={cn("flex h-14 items-center gap-2 border-b border-gray-100 px-4", collapsed && "justify-center px-0")}>
      {brand.logoUrl ? (
        // eslint-disable-next-line @next/next/no-img-element
        <img src={brand.logoUrl} alt={brand.name} className="h-8 w-8 shrink-0 rounded-lg object-contain" />
      ) : (
        <span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[var(--brand)] text-sm font-bold text-white">{brand.name.slice(0, 2).toUpperCase()}</span>
      )}
      {!collapsed && <span className="truncate text-sm font-bold tracking-tight text-gray-900">{brand.name}</span>}
    </div>
  );

  return (
    <div className="fixed inset-0 flex bg-[var(--background)]">
      {/* Desktop sidebar */}
      <aside className={cn("hidden shrink-0 flex-col border-r border-gray-200 bg-white transition-[width] duration-200 lg:flex", collapsed ? "w-16" : "w-60")}>
        <Brand collapsed={collapsed} />
        <NavLinks collapsed={collapsed} />
        <div className="border-t border-gray-100 p-2">
          <button
            onClick={() => setCollapsed((c) => !c)}
            className={cn("flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium text-gray-500 hover:bg-gray-100", collapsed && "justify-center px-0")}
          >
            {collapsed ? <PanelLeftOpen className="h-[18px] w-[18px]" /> : <PanelLeftClose className="h-[18px] w-[18px]" />}
            {!collapsed && <span>Collapse</span>}
          </button>
        </div>
      </aside>

      {/* Mobile drawer */}
      {drawer && (
        <div className="lg:hidden">
          <div className="pn-fade-in fixed inset-0 z-40 bg-slate-900/40" onClick={() => setDrawer(false)} />
          <aside className="fixed inset-y-0 left-0 z-50 flex w-64 flex-col border-r border-gray-200 bg-white">
            <div className="flex items-center justify-between pr-2">
              <Brand collapsed={false} />
              <button onClick={() => setDrawer(false)} className="text-gray-400 hover:text-gray-600"><X className="h-5 w-5" /></button>
            </div>
            <NavLinks collapsed={false} />
          </aside>
        </div>
      )}

      {/* Main column */}
      <div className="flex min-w-0 flex-1 flex-col">
        <header className="flex h-14 shrink-0 items-center justify-between border-b border-gray-200 bg-white px-4 sm:px-6">
          <div className="flex items-center gap-3">
            <button onClick={() => setDrawer(true)} className="text-gray-500 hover:text-gray-700 lg:hidden"><Menu className="h-5 w-5" /></button>
            <span className="text-sm font-semibold text-gray-500">Affiliate portal</span>
          </div>
          <div className="flex items-center gap-3">
            <span className="hidden text-sm text-gray-600 sm:inline">Hi, {me.name}</span>
            <button
              onClick={() => { auth.clear(); setMe(null); }}
              className="inline-flex items-center gap-1.5 rounded-lg border border-gray-300 px-3 py-1.5 text-xs font-medium text-gray-600 hover:bg-gray-50"
            >
              <LogOut className="h-3.5 w-3.5" /> Log out
            </button>
          </div>
        </header>
        <main className="flex-1 overflow-y-auto p-4 sm:p-6 lg:px-8">
          <div className="mx-auto max-w-[1280px]">{children}</div>
        </main>
      </div>
    </div>
  );
}

function LoginGate({ onLogin, brand }: { onLogin: (a: { id: string; name: string }) => void; brand: { logoUrl: string | null; name: string } }) {
  const [form, setForm] = useState({ email: "", password: "" });
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    setBusy(true);
    setError("");
    try {
      const r = await api.post("/affiliates/login", form);
      auth.save(r.id, r.name, r.token);
      onLogin({ id: r.id, name: r.name });
    } catch (err) {
      setError((err as Error).message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="fixed inset-0 flex items-center justify-center bg-[var(--background)] p-4">
      <div className="w-full max-w-sm">
        <div className="mb-6 text-center">
          {brand.logoUrl ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={brand.logoUrl} alt={brand.name} className="mx-auto h-12 w-12 rounded-xl object-contain" />
          ) : (
            <span className="mx-auto flex h-11 w-11 items-center justify-center rounded-xl bg-[var(--brand)] text-base font-bold text-white">{brand.name.slice(0, 2).toUpperCase()}</span>
          )}
          <h1 className="mt-3 text-xl font-bold text-gray-900">{brand.name}</h1>
          <p className="text-sm text-gray-500">Log in to track your earnings</p>
        </div>
        <form onSubmit={submit} className="space-y-4 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
          <FormField label="Email">
            <Input type="email" required value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
          </FormField>
          <FormField label="Password" error={error}>
            <Input type="password" required error={!!error} value={form.password} onChange={(e) => setForm({ ...form, password: e.target.value })} />
          </FormField>
          <Button type="submit" loading={busy} className="w-full">Log in</Button>
          <p className="text-center text-sm text-gray-500">
            No account? <Link href="/signup" className="font-medium text-[var(--brand)] hover:underline">Sign up</Link>
          </p>
        </form>
      </div>
    </div>
  );
}
