"use client";

import Link from "next/link";
import { useRouter, usePathname } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import { useSession } from "@/components/session-provider";
import { Avatar, IconButton } from "@/components/ui";
import { InstallButton } from "@/components/install-button";
import { NotificationBell } from "@/components/notification-bell";
import { api } from "@/lib/api-client";
import { LANGUAGES } from "@/lib/constants";
import { formatCount } from "@/lib/format";

type Suggestion = { text: string; source: string };
type SubscribedChannel = {
  channelId: string;
  name: string;
  handle: string;
  avatarUrl: string | null;
  isLive: boolean;
  subscriberCount: number;
};

function Logo() {
  return (
    <Link href="/" className="flex shrink-0 items-center gap-1.5" aria-label="PlayTube home">
      <span className="grid h-7 w-10 place-items-center rounded-md bg-brand shadow-lg">
        <svg viewBox="0 0 24 24" className="h-4 w-4 text-white" fill="currentColor" aria-hidden>
          <path d="M8 5v14l11-7z" />
        </svg>
      </span>
      <span className="text-xl font-bold tracking-tight">
        Play<span className="text-brand">Tube</span>
      </span>
    </Link>
  );
}

function SearchBar({ onNavigate }: { onNavigate?: () => void }) {
  const router = useRouter();
  const [value, setValue] = useState("");
  const [suggestions, setSuggestions] = useState<Suggestion[]>([]);
  const [trending, setTrending] = useState<string[]>([]);
  const [open, setOpen] = useState(false);
  const [activeIndex, setActiveIndex] = useState(-1);
  const boxRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const handler = (event: MouseEvent) => {
      if (boxRef.current && !boxRef.current.contains(event.target as Node)) setOpen(false);
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  useEffect(() => {
    const handle = setTimeout(() => {
      if (!value.trim()) {
        setSuggestions([]);
        return;
      }
      void api<{ suggestions: Suggestion[] }>(`/api/search/suggest?q=${encodeURIComponent(value)}`)
        .then((data) => setSuggestions(data.suggestions))
        .catch(() => undefined);
    }, 180);
    return () => clearTimeout(handle);
  }, [value]);

  useEffect(() => {
    void api<{ trending: string[] }>("/api/search/suggest?q=")
      .then((data) => setTrending(data.trending))
      .catch(() => undefined);
  }, []);

  const submit = (query: string) => {
    const q = query.trim();
    if (!q) return;
    setOpen(false);
    onNavigate?.();
    router.push(`/results?q=${encodeURIComponent(q)}`);
  };

  const list = value.trim() ? suggestions : trending.map((t) => ({ text: t, source: "trending" }));

  return (
    <div className="relative flex-1" ref={boxRef}>
      <form
        onSubmit={(event) => {
          event.preventDefault();
          submit(value);
        }}
        role="search"
        className="flex"
      >
        <div className="flex h-10 flex-1 items-center rounded-l-full border border-line bg-bg pl-4 focus-within:border-brand">
          {open ? (
            <svg viewBox="0 0 24 24" className="mr-2 h-5 w-5 text-muted" fill="currentColor" aria-hidden>
              <path d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 1 0-.7.7l.27.28v.79l5 4.99L20.49 19zm-6 0A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14z" />
            </svg>
          ) : null}
          <input
            value={value}
            onChange={(event) => {
              setValue(event.target.value);
              setOpen(true);
              setActiveIndex(-1);
            }}
            onFocus={() => setOpen(true)}
            onKeyDown={(event) => {
              if (event.key === "ArrowDown") {
                event.preventDefault();
                setActiveIndex((i) => Math.min(i + 1, list.length - 1));
              } else if (event.key === "ArrowUp") {
                event.preventDefault();
                setActiveIndex((i) => Math.max(i - 1, -1));
              } else if (event.key === "Enter" && activeIndex >= 0) {
                event.preventDefault();
                submit(list[activeIndex].text);
              }
            }}
            placeholder="Search PlayTube"
            aria-label="Search PlayTube"
            className="h-full w-full bg-transparent text-sm outline-none placeholder:text-muted"
          />
        </div>
        <button
          type="submit"
          aria-label="Search"
          className="grid h-10 w-16 place-items-center rounded-r-full border border-l-0 border-line bg-surface hover:bg-surface-hover"
        >
          <svg viewBox="0 0 24 24" className="h-5 w-5" fill="currentColor" aria-hidden>
            <path d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 1 0-.7.7l.27.28v.79l5 4.99L20.49 19zm-6 0A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14z" />
          </svg>
        </button>
      </form>

      {open && list.length > 0 ? (
        <div className="absolute left-0 right-16 top-11 z-50 overflow-hidden rounded-xl border border-line bg-bg-elevated shadow-2xl">
          {list.map((item, index) => (
            <button
              key={`${item.source}-${item.text}`}
              onMouseDown={(event) => {
                event.preventDefault();
                submit(item.text);
              }}
              className={`flex w-full items-center gap-3 px-4 py-2.5 text-left text-sm hover:bg-surface ${index === activeIndex ? "bg-surface" : ""}`}
            >
              <svg viewBox="0 0 24 24" className="h-4 w-4 shrink-0 text-muted" fill="currentColor" aria-hidden>
                <path d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 1 0-.7.7l.27.28v.79l5 4.99L20.49 19zm-6 0A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14z" />
              </svg>
              <span className="flex-1 truncate">{item.text}</span>
              <span className="text-[11px] uppercase text-muted">{item.source}</span>
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}

const MAIN_NAV = [
  { href: "/", key: "home", icon: "M12 3 2 12h3v9h6v-6h2v6h6v-9h3z" },
  { href: "/shorts", key: "shorts", icon: "M10 8l6 4-6 4zM4 6h3v12H4zm13 0h3v12h-3z" },
  { href: "/subscriptions", key: "subscriptions", icon: "M4 6h16v2H4zm2-3h12v2H6zM4 11h16v10H4zm6 2v6l5-3z" },
  { href: "/live", key: "live", icon: "M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm-5 3a5 5 0 0 1 .2-1.4L5 8.4A7.9 7.9 0 0 0 4 12c0 1.3.3 2.6.9 3.6l2.2-2.2A5 5 0 0 1 7 12zm10 0a5 5 0 0 1-.2 1.4l2.2 2.2A7.9 7.9 0 0 0 20 12c0-1.3-.3-2.6-.9-3.6l-2.2 2.2A5 5 0 0 1 17 12zM2 12a10 10 0 0 1 3-7.1L3.6 3.5A12 12 0 0 0 0 12s1.5 5 4.5 7.5l1.4-1.4A10 10 0 0 1 2 12zm20 0a10 10 0 0 1-3 7.1l1.4 1.4A12 12 0 0 0 24 12s-1.5-5-4.5-7.5l-1.4 1.4A10 10 0 0 1 22 12z" },
];

const YOU_NAV = [
  { href: "/history", key: "history" },
  { href: "/playlists", key: "playlists" },
  { href: "/playlist/watch_later", key: "watchLater" },
  { href: "/playlist/liked", key: "liked" },
];

function NavIcon({ path }: { path: string }) {
  return (
    <svg viewBox="0 0 24 24" className="h-6 w-6" fill="currentColor" aria-hidden>
      <path d={path} />
    </svg>
  );
}

function SidebarContent({ onNavigate }: { onNavigate?: () => void }) {
  const { user, channel, categories, t, lang, setLang } = useSession();
  const [subs, setSubs] = useState<SubscribedChannel[]>([]);

  useEffect(() => {
    if (!user) return;
    void api<{ items: SubscribedChannel[] }>("/api/subscriptions")
      .then((data) => setSubs(data.items))
      .catch(() => undefined);
  }, [user]);

  return (
    <nav className="flex h-full flex-col gap-4 overflow-y-auto px-3 pb-24 pt-2" aria-label="Main">
      <div className="space-y-1">
        {MAIN_NAV.map((item) => (
          <Link
            key={item.href}
            href={item.href}
            onClick={onNavigate}
            className="flex items-center gap-5 rounded-xl px-3 py-2.5 text-sm font-medium transition hover:bg-surface"
          >
            <NavIcon path={item.icon} />
            <span className="truncate">{t(item.key)}</span>
          </Link>
        ))}
      </div>

      <div className="border-t border-line pt-3">
        <p className="px-3 pb-1 text-base font-semibold">{user ? channel?.name ?? t("library") : t("library")}</p>
        <div className="space-y-1">
          {YOU_NAV.map((item) => (
            <Link
              key={item.href}
              href={item.href}
              onClick={onNavigate}
              className="flex items-center gap-5 rounded-xl px-3 py-2 text-sm transition hover:bg-surface"
            >
              <span aria-hidden className="grid h-6 w-6 place-items-center text-base">
                {item.key === "history" ? "🕘" : item.key === "playlists" ? "📁" : item.key === "watchLater" ? "⏰" : "👍"}
              </span>
              {t(item.key)}
            </Link>
          ))}
          <Link href="/notifications" onClick={onNavigate} className="flex items-center gap-5 rounded-xl px-3 py-2 text-sm hover:bg-surface">
            <span aria-hidden className="grid h-6 w-6 place-items-center text-base">🔔</span>
            {t("notifications")}
          </Link>
        </div>
      </div>

      {subs.length > 0 ? (
        <div className="border-t border-line pt-3">
          <p className="px-3 pb-1 text-sm font-semibold uppercase tracking-wide text-muted">{t("subscriptions")}</p>
          <div className="space-y-1">
            {subs.slice(0, 12).map((sub) => (
              <Link
                key={sub.channelId}
                href={`/channel/${sub.handle}`}
                onClick={onNavigate}
                className="flex items-center gap-4 rounded-xl px-3 py-2 text-sm hover:bg-surface"
              >
                <Avatar name={sub.name} src={sub.avatarUrl} size={24} />
                <span className="flex-1 truncate">{sub.name}</span>
                {sub.isLive ? <span className="h-2 w-2 rounded-full bg-brand live-dot" aria-label="live" /> : null}
              </Link>
            ))}
          </div>
        </div>
      ) : null}

      <div className="border-t border-line pt-3">
        <p className="px-3 pb-1 text-sm font-semibold uppercase tracking-wide text-muted">Explore</p>
        <div className="flex flex-wrap gap-2 px-3 pb-2">
          {categories
            .filter((c) => c.slug !== "all")
            .map((category) => (
              <Link
                key={category.slug}
                href={`/?category=${category.slug}`}
                onClick={onNavigate}
                className="rounded-lg bg-chip px-2.5 py-1 text-xs font-medium hover:bg-surface-hover"
              >
                {category.emoji} {category.name}
              </Link>
            ))}
        </div>
      </div>

      <div className="border-t border-line pt-3">
        <div className="space-y-1">
          {channel ? (
            <Link href="/studio" onClick={onNavigate} className="flex items-center gap-5 rounded-xl px-3 py-2 text-sm hover:bg-surface">
              <span aria-hidden className="grid h-6 w-6 place-items-center text-base">🎛️</span>
              {t("studio")}
            </Link>
          ) : null}
          {user?.role === "admin" ? (
            <Link href="/admin" onClick={onNavigate} className="flex items-center gap-5 rounded-xl px-3 py-2 text-sm hover:bg-surface">
              <span aria-hidden className="grid h-6 w-6 place-items-center text-base">🛡️</span>
              {t("admin")}
            </Link>
          ) : null}
          <Link href="/settings" onClick={onNavigate} className="flex items-center gap-5 rounded-xl px-3 py-2 text-sm hover:bg-surface">
            <span aria-hidden className="grid h-6 w-6 place-items-center text-base">⚙️</span>
            {t("settings")}
          </Link>
          <div className="px-1 py-1">
            <InstallButton variant="menu" />
          </div>
        </div>
      </div>

      <div className="border-t border-line pt-3">
        <label className="px-3 pb-1 block text-[11px] font-semibold uppercase tracking-wide text-muted" htmlFor="pt-lang">
          Language
        </label>
        <select
          id="pt-lang"
          value={lang}
          onChange={(event) => setLang(event.target.value)}
          className="mx-3 w-[calc(100%-1.5rem)] rounded-lg border border-line bg-surface px-2 py-1.5 text-sm"
        >
          {LANGUAGES.map((language) => (
            <option key={language.code} value={language.code}>
              {language.label}
            </option>
          ))}
        </select>
        <p className="px-3 pt-4 text-[11px] leading-relaxed text-muted">
          PlayTube · {formatCount(128000)} creators · © {new Date().getFullYear()}
        </p>
      </div>
    </nav>
  );
}

function AccountMenu() {
  const { user, channel, theme, setTheme, logout, t } = useSession();
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement | null>(null);
  const router = useRouter();

  useEffect(() => {
    const handler = (event: MouseEvent) => {
      if (ref.current && !ref.current.contains(event.target as Node)) setOpen(false);
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  if (!user) {
    return (
      <Link
        href="/login"
        className="inline-flex items-center gap-2 rounded-full border border-brand px-3 py-1.5 text-sm font-semibold text-brand transition hover:bg-brand/10"
      >
        <span aria-hidden>👤</span>
        <span className="hidden sm:inline">{t("signIn")}</span>
      </Link>
    );
  }

  return (
    <div className="relative" ref={ref}>
      <button onClick={() => setOpen((v) => !v)} aria-label="Account menu" className="rounded-full">
        <Avatar name={user.displayName} src={user.avatarUrl} size={32} />
      </button>
      {open ? (
        <div className="animate-fade-up absolute right-0 top-11 z-50 w-64 overflow-hidden rounded-xl border border-line bg-bg-elevated shadow-2xl">
          <div className="border-b border-line p-4">
            <div className="flex items-center gap-3">
              <Avatar name={user.displayName} src={user.avatarUrl} size={40} />
              <div className="min-w-0">
                <p className="truncate text-sm font-semibold">{user.displayName}</p>
                <p className="truncate text-xs text-muted">{user.email}</p>
              </div>
            </div>
            {channel ? (
              <Link
                href={`/channel/${channel.handle}`}
                onClick={() => setOpen(false)}
                className="mt-3 block rounded-full bg-surface px-3 py-1.5 text-center text-sm font-semibold text-brand"
              >
                View my channel
              </Link>
            ) : (
              <button
                onClick={async () => {
                  await api("/api/channels", { method: "POST", json: { name: user.displayName } });
                  setOpen(false);
                  router.refresh();
                }}
                className="mt-3 w-full rounded-full bg-brand px-3 py-1.5 text-sm font-semibold text-white"
              >
                Create a channel
              </button>
            )}
          </div>
          <div className="p-2 text-sm">
            <Link href="/studio" onClick={() => setOpen(false)} className="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-surface">
              🎛️ Creator Studio
            </Link>
            <Link href="/settings" onClick={() => setOpen(false)} className="flex items-center gap-3 rounded-lg px-3 py-2 hover:bg-surface">
              ⚙️ {t("settings")}
            </Link>
            <button
              onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
              className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left hover:bg-surface"
            >
              {theme === "dark" ? "☀️ Light mode" : "🌙 Dark mode"}
            </button>
            <div className="px-1 py-1">
              <InstallButton variant="menu" />
            </div>
            <button onClick={() => void logout()} className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left hover:bg-surface">
              🚪 {t("signOut")}
            </button>
          </div>
        </div>
      ) : null}
    </div>
  );
}

export function AppShell({ children }: { children: React.ReactNode }) {
  const { t, theme, setTheme } = useSession();
  const pathname = usePathname();
  const [collapsed, setCollapsed] = useState(false);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [uploadOpen, setUploadOpen] = useState(false);
  const isShorts = pathname?.startsWith("/shorts");
  const isWatch = pathname?.startsWith("/watch") || pathname?.startsWith("/live");

  useEffect(() => {
    try {
      setCollapsed(localStorage.getItem("playtube-sidebar") === "1");
    } catch {}
  }, []);

  const closeDrawer = useCallback(() => setDrawerOpen(false), []);

  // Android hardware back button / browser back closes overlays first.
  useEffect(() => {
    if (!drawerOpen) return;
    window.history.pushState({ drawer: true }, "");
    const onPop = () => setDrawerOpen(false);
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, [drawerOpen]);

  useEffect(() => {
    const onBackButton = (event: Event) => {
      if (drawerOpen) {
        event.preventDefault();
        setDrawerOpen(false);
      }
    };
    document.addEventListener("backbutton", onBackButton);
    return () => document.removeEventListener("backbutton", onBackButton);
  }, [drawerOpen]);

  return (
    <div className="min-h-dvh bg-bg text-fg">
      <header className="sticky top-0 z-40 flex h-14 items-center gap-2 bg-bg px-2 sm:px-4">
        <IconButton
          label="Toggle menu"
          onClick={() => {
            if (window.innerWidth < 1024) setDrawerOpen(true);
            else {
              setCollapsed((v) => {
                try {
                  localStorage.setItem("playtube-sidebar", v ? "0" : "1");
                } catch {}
                return !v;
              });
            }
          }}
        >
          <svg viewBox="0 0 24 24" className="h-6 w-6" fill="currentColor" aria-hidden>
            <path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z" />
          </svg>
        </IconButton>
        <Logo />
        <div className="mx-auto hidden max-w-2xl flex-1 sm:block">
          <SearchBar />
        </div>
        <div className="ml-auto flex items-center gap-1 sm:gap-2">
          <Link
            href="/studio/upload"
            className="hidden items-center gap-2 rounded-full bg-surface px-3 py-1.5 text-sm font-medium hover:bg-surface-hover sm:inline-flex"
          >
            <span aria-hidden>🎥</span> Create
          </Link>
          <IconButton label={theme === "dark" ? "Light mode" : "Dark mode"} onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
            <span aria-hidden className="text-lg">{theme === "dark" ? "☀️" : "🌙"}</span>
          </IconButton>
          <InstallButton />
          <NotificationBell />
          <AccountMenu />
        </div>
      </header>

      <div className="px-2 pb-2 sm:hidden">
        <SearchBar onNavigate={closeDrawer} />
      </div>

      <div className="flex">
        <aside
          className={`sticky top-14 hidden h-[calc(100dvh-3.5rem)] shrink-0 lg:block ${
            collapsed ? "w-[72px]" : "w-60"
          } transition-[width] duration-200`}
        >
          <SidebarContent />
        </aside>

        {drawerOpen ? (
          <div className="fixed inset-0 z-50 lg:hidden">
            <button className="absolute inset-0 bg-black/60" aria-label="Close menu" onClick={closeDrawer} />
            <div className="animate-fade-up absolute left-0 top-0 h-full w-64 bg-bg shadow-2xl">
              <div className="flex h-14 items-center gap-3 px-4">
                <IconButton label="Close menu" onClick={closeDrawer}>
                  <svg viewBox="0 0 24 24" className="h-6 w-6" fill="currentColor" aria-hidden>
                    <path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
                  </svg>
                </IconButton>
                <Logo />
              </div>
              <div className="h-[calc(100%-3.5rem)]">
                <SidebarContent onNavigate={closeDrawer} />
              </div>
            </div>
          </div>
        ) : null}

        <main className={`min-w-0 flex-1 ${isShorts ? "" : isWatch ? "pb-24 lg:pb-6" : "pb-24 lg:pb-10"}`}>{children}</main>
      </div>

      <nav className="fixed bottom-0 left-0 right-0 z-40 grid grid-cols-5 border-t border-line bg-bg lg:hidden" aria-label="Mobile">
        {[
          { href: "/", label: t("home"), icon: "M12 3 2 12h3v9h6v-6h2v6h6v-9h3z" },
          { href: "/shorts", label: t("shorts"), icon: "M10 8l6 4-6 4zM4 6h3v12H4zm13 0h3v12h-3z" },
          { href: "/studio/upload", label: "Create", icon: "M11 5h2v6h6v2h-6v6h-2v-6H5v-2h6z" },
          { href: "/subscriptions", label: t("subscriptions"), icon: "M4 6h16v2H4zm2-3h12v2H6zM4 11h16v10H4zm6 2v6l5-3z" },
          { href: "/playlists", label: t("library"), icon: "M4 6h2v12H4zm4 0h2v12H8zm5 .5 6 3.5-6 3.5z" },
        ].map((item) => {
          const active = pathname === item.href;
          return (
            <Link
              key={item.href}
              href={item.href}
              className={`flex flex-col items-center gap-0.5 py-2 text-[10px] font-medium ${active ? "text-brand" : "text-muted"}`}
            >
              <svg viewBox="0 0 24 24" className="h-5 w-5" fill="currentColor" aria-hidden>
                <path d={item.icon} />
              </svg>
              {item.label}
            </Link>
          );
        })}
      </nav>

      {uploadOpen ? null : null}
    </div>
  );
}
