"use client";

import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { signOut } from "next-auth/react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
  Activity,
  Bot,
  Boxes,
  BrainCircuit,
  Check,
  ChevronLeft,
  CircleAlert,
  Command,
  Database,
  Gauge,
  Languages,
  LogOut,
  Mail,
  MapPinned,
  Menu,
  Moon,
  PackageSearch,
  Search,
  Send,
  Settings2,
  ShieldCheck,
  Sun,
  Warehouse,
  X,
} from "lucide-react";
import { useEffect, useMemo, useRef, useState, useTransition } from "react";
import type { ComponentType, ReactNode } from "react";
import { simulateOrder } from "@/app/(dashboard)/actions";
import { usePreferences, useToast } from "@/components/providers/app-providers";

interface DashboardShellProps {
  children: ReactNode;
  user: {
    name?: string | null;
    email?: string | null;
    role: "ADMIN" | "AGENT";
  };
}

interface InfrastructureResponse {
  database: "connected" | "offline";
  n8n: { status: "ok" | "error" | "unconfigured"; activeWorkflows: number; nodes: number };
  telegram: "configured" | "missing";
  smtp: "configured" | "missing";
  checkedAt: string;
}

interface SearchOrder {
  id: string;
  status: string;
  codAmount: string;
  currency: string;
  customer: { name: string; phoneE164: string };
}

const navigation: Array<{
  href: string;
  key: "overview" | "board" | "map" | "inventory" | "aiLogs" | "settings";
  icon: ComponentType<{ size?: number; strokeWidth?: number }>;
  adminOnly?: boolean;
}> = [
  { href: "/", key: "overview", icon: Gauge },
  { href: "/board", key: "board", icon: PackageSearch },
  { href: "/map", key: "map", icon: MapPinned },
  { href: "/inventory", key: "inventory", icon: Warehouse },
  { href: "/ai-logs", key: "aiLogs", icon: BrainCircuit },
  { href: "/settings", key: "settings", icon: Settings2, adminOnly: true },
];

async function fetchInfrastructure() {
  const response = await fetch("/api/dashboard/infrastructure", { cache: "no-store" });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return (await response.json()) as InfrastructureResponse;
}

async function searchOrders(query: string) {
  const response = await fetch(`/api/dashboard/search?q=${encodeURIComponent(query)}`, { cache: "no-store" });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return (await response.json()) as { data: SearchOrder[] };
}

export function DashboardShell({ children, user }: DashboardShellProps) {
  const pathname = usePathname();
  const router = useRouter();
  const queryClient = useQueryClient();
  const notify = useToast();
  const { dictionary: t, locale, theme, toggleLocale, toggleTheme } = usePreferences();
  const [mobileOpen, setMobileOpen] = useState(false);
  const [searchOpen, setSearchOpen] = useState(false);
  const [search, setSearch] = useState("");
  const [accountOpen, setAccountOpen] = useState(false);
  const [simulating, startSimulation] = useTransition();

  useEffect(() => {
    const handleKey = (event: KeyboardEvent) => {
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
        event.preventDefault();
        setSearchOpen(true);
      }
      if (event.key === "Escape") setSearchOpen(false);
    };
    window.addEventListener("keydown", handleKey);
    return () => window.removeEventListener("keydown", handleKey);
  }, []);

  useEffect(() => {
    setMobileOpen(false);
  }, [pathname]);

  const infrastructure = useQuery({
    queryKey: ["infrastructure"],
    queryFn: fetchInfrastructure,
    refetchInterval: 5_000,
  });

  function runSimulation() {
    startSimulation(async () => {
      const result = await simulateOrder();
      if (!result.ok) {
        notify(t.dashboard.simulate.failure, "error");
        return;
      }
      const message = result.fraud ? t.dashboard.simulate.fraud : t.dashboard.simulate.success;
      notify(
        `${message}: ${result.order.orderId ?? "—"} · ${t.dashboard.simulate.status}: ${result.order.status ?? "—"}`,
        "success",
      );
      await Promise.all([
        queryClient.invalidateQueries({ queryKey: ["orders"] }),
        queryClient.invalidateQueries({ queryKey: ["search"] }),
      ]);
      if (result.order.orderId) setSearch(result.order.orderId);
    });
  }

  return (
    <div className="dashboard-shell">
      {mobileOpen ? <button className="sidebar-scrim" onClick={() => setMobileOpen(false)} aria-label={t.dashboard.search.close} /> : null}
      <aside className={`dashboard-sidebar ${mobileOpen ? "is-open" : ""}`}>
        <div className="sidebar-brand">
          <span className="brand-shield"><ShieldCheck size={27} strokeWidth={1.8} /></span>
          <div className="brand-copy">
            <div className="brand-title-row">
              <strong>{t.dashboard.brand}</strong>
              <span className="enterprise-badge">{t.dashboard.badge}</span>
            </div>
            <p>{t.dashboard.subtitle}</p>
          </div>
          <button className="sidebar-close" onClick={() => setMobileOpen(false)} aria-label={t.dashboard.search.close}>
            <X size={18} />
          </button>
        </div>

        <div className="sidebar-rule" />
        <p className="sidebar-label">{t.dashboard.mainMenu}</p>
        <nav className="sidebar-nav">
          {navigation.map((item) => {
            if (item.adminOnly && user.role !== "ADMIN") return null;
            const active = item.href === "/" ? pathname === "/" : pathname.startsWith(item.href);
            const Icon = item.icon;
            return (
              <Link className={`nav-link ${active ? "active" : ""}`} href={item.href} key={item.href} aria-current={active ? "page" : undefined}>
                <Icon size={19} strokeWidth={1.8} />
                <span>{t.dashboard.navigation[item.key]}</span>
                {active ? <span className="nav-active-dot" /> : null}
              </Link>
            );
          })}
        </nav>

        <InfrastructureCard data={infrastructure.data} loading={infrastructure.isLoading} error={infrastructure.isError} />

        <button className="sidebar-user" onClick={() => setAccountOpen((current) => !current)} type="button" aria-label={t.dashboard.header.account}>
          <span className="user-avatar">{(user.name || user.email || "U").slice(0, 1).toUpperCase()}</span>
          <span className="user-copy">
            <strong>{user.name || user.email}</strong>
            <small>{t.dashboard.roles[user.role]}</small>
          </span>
          <ChevronLeft className={accountOpen ? "rotate-down" : ""} size={17} />
        </button>
        {accountOpen ? (
          <button className="logout-button" onClick={() => signOut({ callbackUrl: "/login" })} type="button">
            <LogOut size={17} /> {t.dashboard.header.logout}
          </button>
        ) : null}
      </aside>

      <section className="dashboard-stage">
        <header className="dashboard-header">
          <button className="mobile-menu-button" onClick={() => setMobileOpen(true)} aria-label={t.dashboard.header.menu}>
            <Menu size={20} />
          </button>
          <button className="global-search-trigger" onClick={() => setSearchOpen(true)} type="button">
            <Search size={18} />
            <span>{t.dashboard.header.searchPlaceholder}</span>
            <kbd><Command size={12} />K</kbd>
          </button>
          <div className="header-actions">
            <span className={`crm-pill ${infrastructure.data?.database === "connected" ? "online" : ""}`}>
              <span className="status-dot" />
              <Database size={15} />
              {t.dashboard.header.crmConnected}
            </span>
            <button className="language-button" onClick={toggleLocale} type="button">
              <Languages size={16} /> {t.dashboard.header.language}
            </button>
            <button className="icon-button" onClick={toggleTheme} type="button" aria-label={t.dashboard.header.theme}>
              {theme === "dark" ? <Sun size={18} /> : <Moon size={18} />}
            </button>
            <button className="simulate-button" disabled={simulating} onClick={runSimulation} type="button">
              <Send size={17} />
              <span>{simulating ? t.dashboard.header.simulating : t.dashboard.header.simulate}</span>
            </button>
            {user.role === "ADMIN" ? (
              <Link className="settings-button" href="/settings" aria-label={t.dashboard.header.settings}>
                <Settings2 size={19} />
              </Link>
            ) : null}
          </div>
        </header>

        <main className="dashboard-main">{children}</main>
      </section>

      <SearchPalette
        open={searchOpen}
        query={search}
        setQuery={setSearch}
        close={() => setSearchOpen(false)}
        onNavigate={(href) => {
          setSearchOpen(false);
          router.push(href);
        }}
      />
    </div>
  );
}

function InfrastructureCard({ data, loading, error }: { data?: InfrastructureResponse; loading: boolean; error: boolean }) {
  const { dictionary: t } = usePreferences();
  const n8nState = error || data?.n8n.status === "error" ? "offline" : data?.n8n.status === "ok" ? "connected" : "checking";
  const databaseState = data?.database === "connected" ? "connected" : loading ? "checking" : "offline";
  return (
    <section className="infrastructure-card">
      <div className="infrastructure-title"><Activity size={16} />{t.dashboard.infrastructure.title}</div>
      <StatusRow
        icon={Bot}
        label={t.dashboard.infrastructure.n8n}
        state={n8nState}
        value={n8nState === "connected" ? `${t.dashboard.infrastructure.nodes} ${data?.n8n.nodes ?? 0}` : undefined}
      />
      <StatusRow icon={Database} label={t.dashboard.infrastructure.postgres} state={databaseState} />
      <StatusRow
        icon={Send}
        label={t.dashboard.infrastructure.telegram}
        state={data?.telegram === "configured" ? "configured" : loading ? "checking" : "missing"}
      />
      <StatusRow
        icon={Mail}
        label={t.dashboard.infrastructure.smtp}
        state={data?.smtp === "configured" ? "configured" : loading ? "checking" : "missing"}
      />
    </section>
  );
}

function StatusRow({
  icon: Icon,
  label,
  state,
  value,
}: {
  icon: ComponentType<{ size?: number }>;
  label: string;
  state: "connected" | "configured" | "missing" | "checking" | "offline";
  value?: string;
}) {
  const { dictionary: t } = usePreferences();
  const text = value ?? {
    connected: t.dashboard.infrastructure.connected,
    configured: t.dashboard.infrastructure.configured,
    missing: t.dashboard.infrastructure.missing,
    checking: t.dashboard.infrastructure.checking,
    offline: t.dashboard.infrastructure.offline,
  }[state];
  return (
    <div className="status-row">
      <span><Icon size={14} />{label}</span>
      <strong className={`status-${state}`}>{text}</strong>
    </div>
  );
}

function SearchPalette({
  open,
  query,
  setQuery,
  close,
  onNavigate,
}: {
  open: boolean;
  query: string;
  setQuery: (value: string) => void;
  close: () => void;
  onNavigate: (href: string) => void;
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const { dictionary: t, locale } = usePreferences();
  const results = useQuery({
    queryKey: ["search", query],
    queryFn: () => searchOrders(query),
    enabled: open && query.trim().length >= 2,
    staleTime: 0,
  });

  useEffect(() => {
    if (open) window.setTimeout(() => inputRef.current?.focus(), 30);
  }, [open]);

  const formatter = useMemo(
    () => new Intl.NumberFormat(locale === "ar" ? "ar-EG" : "en-US", { maximumFractionDigits: 2 }),
    [locale],
  );

  if (!open) return null;
  const orders = results.data?.data ?? [];

  return (
    <div className="command-backdrop" role="presentation" onMouseDown={(event) => event.target === event.currentTarget && close()}>
      <section className="command-palette" role="dialog" aria-modal="true" aria-labelledby="command-title">
        <div className="command-heading">
          <div><p className="eyebrow">{t.dashboard.search.description}</p><h2 id="command-title">{t.dashboard.search.title}</h2></div>
          <button className="icon-button" onClick={close} aria-label={t.dashboard.search.close}><X size={18} /></button>
        </div>
        <label className="command-input">
          <Search size={19} />
          <input ref={inputRef} value={query} onChange={(event) => setQuery(event.target.value)} placeholder={t.dashboard.search.input} />
          <kbd>ESC</kbd>
        </label>
        <div className="command-results">
          {query.trim().length < 2 ? <CommandEmpty icon={Search} text={t.dashboard.search.hint} /> : null}
          {results.isFetching ? <CommandEmpty icon={Activity} text={t.dashboard.search.loading} spinning /> : null}
          {!results.isFetching && query.trim().length >= 2 && orders.length === 0 ? (
            <CommandEmpty icon={PackageSearch} text={t.dashboard.search.empty} />
          ) : null}
          {!results.isFetching
            ? orders.map((order) => (
                <button className="search-result" key={order.id} onClick={() => onNavigate(`/orders/${order.id}`)} type="button">
                  <span className="result-icon"><Boxes size={18} /></span>
                  <span className="result-main">
                    <strong className="mono">{order.id}</strong>
                    <small>{order.customer.name} · <bdi>{order.customer.phoneE164}</bdi></small>
                  </span>
                  <span className="result-meta">
                    <span className={`order-status status-chip-${order.status.toLowerCase()}`}>
                      {t.dashboard.status[order.status as keyof typeof t.dashboard.status] ?? order.status}
                    </span>
                    <small>{formatter.format(Number(order.codAmount))} {order.currency}</small>
                  </span>
                  <ChevronLeft size={17} />
                </button>
              ))
            : null}
        </div>
      </section>
    </div>
  );
}

function CommandEmpty({ icon: Icon, text, spinning = false }: { icon: ComponentType<{ size?: number; className?: string }>; text: string; spinning?: boolean }) {
  return <div className="command-empty"><Icon className={spinning ? "spin" : ""} size={24} /><p>{text}</p></div>;
}
