import React from 'react';
import { Link, NavLink, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { LayoutDashboard, CalendarDays, Settings } from 'lucide-react';
import toast from 'react-hot-toast';
import { cn } from '@/lib/utils';
import { Badge } from '@/components/ui/badge';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/components/ui/sheet';
import {
  ADMIN_HOME_PATH,
  ADMIN_EVENTS_PATH,
  ADMIN_EVENT_VIEW_PATH,
  ADMIN_EVENT_PHOTOS_PATH,
  ADMIN_SETTINGS_PATH,
  ADMIN_BILLING_PATH,
} from '../constants';
import { registerApiErrorListener } from '../lib/apiError';
import { getDashboardSummary, getEvents, getTenantPackagesOverview } from '../api';
import { NotificationCenter } from './NotificationCenter';
import { UserMenu } from './UserMenu';
import { useEventContext } from '../context/EventContext';
import { EventSwitcher, EventMenuBar } from './EventNav';
import { useAuth } from '../auth/context';
import { CommandShelf } from './CommandShelf';

type NavItem = {
  key: string;
  to: string;
  label: string;
  icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
  end?: boolean;
  highlight?: boolean;
  prefetchKey?: string;
};

type PageTab = {
  key: string;
  label: string;
  href: string;
  badge?: React.ReactNode;
};

interface AdminLayoutProps {
  title: string;
  subtitle?: string;
  actions?: React.ReactNode;
  children: React.ReactNode;
  disableCommandShelf?: boolean;
  tabs?: PageTab[];
  currentTabKey?: string;
}

export function AdminLayout({ title, subtitle, actions, children, disableCommandShelf, tabs, currentTabKey }: AdminLayoutProps) {
  const { t } = useTranslation('common');
  const prefetchedPathsRef = React.useRef<Set<string>>(new Set());
  const { events } = useEventContext();
  const singleEvent = events.length === 1 ? events[0] : null;
  const eventsPath = singleEvent?.slug ? ADMIN_EVENT_VIEW_PATH(singleEvent.slug) : ADMIN_EVENTS_PATH;
  const eventsLabel = events.length === 1
    ? t('navigation.event', { defaultValue: 'Event' })
    : t('navigation.events');

  const photosPath = singleEvent?.slug ? ADMIN_EVENT_PHOTOS_PATH(singleEvent.slug) : ADMIN_EVENTS_PATH;
  const billingLabel = t('navigation.billing', { defaultValue: 'Paket' });

  const baseNavItems = React.useMemo<NavItem[]>(() => [
    {
      key: 'dashboard',
      to: ADMIN_HOME_PATH,
      label: t('navigation.dashboard'),
      icon: LayoutDashboard,
      end: true,
      prefetchKey: ADMIN_HOME_PATH,
    },
    {
      key: 'events',
      to: eventsPath,
      label: eventsLabel,
      icon: CalendarDays,
      end: Boolean(singleEvent?.slug),
      highlight: events.length === 1,
      prefetchKey: ADMIN_EVENTS_PATH,
    },
    {
      key: 'billing',
      to: ADMIN_BILLING_PATH,
      label: billingLabel,
      icon: Settings,
      prefetchKey: ADMIN_BILLING_PATH,
    },
  ], [eventsLabel, eventsPath, billingLabel, singleEvent, events.length, t]);

  const { user } = useAuth();
  const isMember = user?.role === 'member';

  const navItems = React.useMemo(
    () => baseNavItems.filter((item) => {
      if (!isMember) {
        return true;
      }
      return !['dashboard', 'billing'].includes(item.key);
    }),
    [baseNavItems, isMember],
  );

  const prefetchers = React.useMemo(() => ({
    [ADMIN_HOME_PATH]: () =>
      Promise.all([
        getDashboardSummary(),
        getEvents(),
        getTenantPackagesOverview(),
      ]).then(() => undefined),
    [ADMIN_EVENTS_PATH]: () => getEvents().then(() => undefined),
    [ADMIN_BILLING_PATH]: () => getTenantPackagesOverview().then(() => undefined),
    [ADMIN_SETTINGS_PATH]: () => Promise.resolve(),
  }), []);

  const triggerPrefetch = React.useCallback(
    (path: string) => {
      if (prefetchedPathsRef.current.has(path)) {
        return;
      }

      const runner = prefetchers[path as keyof typeof prefetchers];
      if (!runner) {
        return;
      }

      prefetchedPathsRef.current.add(path);
      Promise.resolve(runner()).catch(() => {
        prefetchedPathsRef.current.delete(path);
      });
    },
    [prefetchers],
  );

  React.useEffect(() => {
    document.body.classList.add('tenant-admin-theme');
    return () => {
      document.body.classList.remove('tenant-admin-theme');
    };
  }, []);

  React.useEffect(() => {
    const unsubscribe = registerApiErrorListener((detail) => {
      const fallback = t('errors.generic');
      const message = detail?.message?.trim() ? detail.message : fallback;
      toast.error(message, {
        id: detail?.code ? `api-error-${detail.code}` : undefined,
      });
    });

    return unsubscribe;
  }, [t]);

  return (
    <div className="relative min-h-svh overflow-hidden bg-gradient-to-br from-rose-50 via-white to-slate-50 text-slate-900 dark:bg-slate-950 dark:text-white">
      <div
        aria-hidden
        className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_10%_10%,rgba(255,137,170,0.25),transparent_55%),radial-gradient(circle_at_80%_0%,rgba(96,165,250,0.22),transparent_60%)] opacity-60 dark:opacity-30"
      />
      <div aria-hidden className="absolute inset-0 bg-gradient-to-b from-white/80 via-white/60 to-transparent dark:from-slate-950 dark:via-slate-950/90 dark:to-slate-950/80" />
      <div className="relative z-10 flex min-h-svh flex-col">
        <header className="sticky top-0 z-40 border-b border-slate-200/70 bg-white/90 backdrop-blur-xl dark:border-white/10 dark:bg-slate-950/80">
          <div className="mx-auto grid w-full max-w-6xl grid-cols-[1fr_auto] items-start gap-3 px-4 py-4 sm:px-6">
            <div className="min-w-0 space-y-1">
              <p className="text-[10px] font-semibold uppercase tracking-[0.4em] text-rose-500 dark:text-rose-200">{t('app.brand')}</p>
              <div>
                <h1 className="text-xl font-semibold text-slate-900 dark:text-white sm:text-2xl">{title}</h1>
                {subtitle ? <p className="text-xs text-slate-600 dark:text-slate-300 sm:text-sm">{subtitle}</p> : null}
              </div>
            </div>
            <div className="flex flex-wrap items-center justify-end gap-2">
              {disableCommandShelf ? <EventSwitcher compact /> : null}
              {actions}
              <NotificationCenter />
              <UserMenu />
            </div>
          </div>
          <nav className="hidden border-t border-slate-200/60 dark:border-white/5 sm:block">
            <div className="mx-auto flex w-full max-w-6xl items-center gap-1 px-4 py-2 sm:px-6">
              {navItems.map((item) => (
                <NavLink
                  key={item.key}
                  to={item.to}
                  end={item.end}
                  onPointerEnter={() => triggerPrefetch(item.prefetchKey ?? item.to)}
                  onFocus={() => triggerPrefetch(item.prefetchKey ?? item.to)}
                  onTouchStart={() => triggerPrefetch(item.prefetchKey ?? item.to)}
                  className={({ isActive }) =>
                    cn(
                      'flex items-center gap-2 rounded-2xl px-3 py-2 text-xs font-semibold uppercase tracking-wide transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-rose-400/60',
                      isActive
                        ? 'bg-rose-600 text-white shadow shadow-rose-300/40'
                        : cn(
                            item.highlight
                              ? 'text-rose-600 dark:text-rose-200'
                              : 'text-slate-500 dark:text-slate-300',
                            'hover:text-slate-900 dark:hover:text-white'
                          )
                    )
                  }
                >
                  <item.icon className="h-4 w-4" />
                  {item.label}
                </NavLink>
              ))}
            </div>
          </nav>
          {disableCommandShelf ? <EventMenuBar /> : <CommandShelf />}
          {tabs && tabs.length ? <PageTabsNav tabs={tabs} currentKey={currentTabKey} /> : null}
        </header>

        <main className="relative z-10 mx-auto w-full max-w-5xl flex-1 px-4 pb-[calc(env(safe-area-inset-bottom,0)+5.5rem)] pt-5 sm:px-6 md:pb-16">
          <div className="space-y-5">{children}</div>
        </main>

        <TenantMobileNav items={navItems} onPrefetch={triggerPrefetch} />
      </div>
    </div>
  );
}

function PageTabsNav({ tabs, currentKey }: { tabs: PageTab[]; currentKey?: string }) {
  const location = useLocation();
  const { t } = useTranslation('common');
  const [mobileOpen, setMobileOpen] = React.useState(false);

  const isActive = (tab: PageTab): boolean => {
    if (currentKey) {
      return tab.key === currentKey;
    }
    return location.pathname === tab.href || location.pathname.startsWith(tab.href);
  };

  const activeTab = React.useMemo(() => tabs.find((tab) => isActive(tab)), [tabs, location.pathname, currentKey]);

  const handleTabClick = React.useCallback(
    (tab: PageTab) => {
      setMobileOpen(false);
      const [path, hash] = tab.href.split('#');
      if (location.pathname === path && hash) {
        window.location.hash = `#${hash}`;
      }
    },
    [location.pathname],
  );

  return (
    <div className="border-t border-slate-200/70 bg-white/80 backdrop-blur dark:border-white/10 dark:bg-slate-950/70">
      <div className="mx-auto flex w-full max-w-6xl flex-col gap-2 px-4 py-2 sm:px-6">
        <div className="hidden gap-2 md:flex">
          {tabs.map((tab) => {
            const active = isActive(tab);
            return (
              <Link
                key={tab.key}
                to={tab.href}
                onClick={() => handleTabClick(tab)}
                className={cn(
                  'flex items-center gap-2 rounded-2xl px-4 py-2 text-sm font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-rose-400/60',
                  active
                    ? 'bg-rose-600 text-white shadow shadow-rose-300/40'
                    : 'bg-white text-slate-600 hover:text-slate-900 dark:bg-white/5 dark:text-slate-300 dark:hover:text-white'
                )}
              >
                <span>{tab.label}</span>
                {tab.badge !== undefined ? (
                  <Badge
                    variant={active ? 'secondary' : 'outline'}
                    className={cn(
                      active ? 'bg-white/20 text-white' : 'text-slate-600 dark:text-slate-300',
                      'rounded-full text-[11px]'
                    )}
                  >
                    {tab.badge}
                  </Badge>
                ) : null}
              </Link>
            );
          })}
        </div>
        <div className="md:hidden">
          <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
            <SheetTrigger asChild>
              <button
                type="button"
                className="flex w-full items-center justify-between rounded-2xl border border-slate-200/70 bg-white px-3 py-2 text-left text-sm font-semibold text-slate-700 shadow-sm dark:border-white/10 dark:bg-white/10 dark:text-slate-200"
              >
                <span>{activeTab?.label ?? t('navigation.tabs.active')}</span>
                <span className="text-xs uppercase tracking-[0.3em] text-rose-500">{t('navigation.tabs.open')}</span>
              </button>
            </SheetTrigger>
            <SheetContent
              side="bottom"
              className="rounded-t-3xl border-t border-slate-200/70 bg-white/95 pb-6 pt-6 dark:border-white/10 dark:bg-slate-950/95"
            >
              <SheetHeader className="px-4 pt-0 text-left">
                <SheetTitle className="text-lg font-semibold text-slate-900 dark:text-white">
                  {t('navigation.tabs.title')}
                </SheetTitle>
                <SheetDescription>
                  {t('navigation.tabs.subtitle')}
                </SheetDescription>
              </SheetHeader>
              <div className="mt-4 grid gap-2 px-4">
                {tabs.map((tab) => {
                  const active = isActive(tab);
                  return (
                    <Link
                      key={`sheet-${tab.key}`}
                      to={tab.href}
                      onClick={() => {
                        handleTabClick(tab);
                        setMobileOpen(false);
                      }}
                      className={cn(
                        'flex items-center justify-between rounded-2xl border px-4 py-3 text-sm font-medium shadow-sm transition',
                        active
                          ? 'border-rose-200 bg-rose-50 text-rose-700'
                          : 'border-slate-200 bg-white text-slate-700 dark:border-white/10 dark:bg-white/5 dark:text-slate-200'
                      )}
                    >
                      <span>{tab.label}</span>
                      {tab.badge !== undefined ? (
                        <Badge
                          variant={active ? 'secondary' : 'outline'}
                          className={cn(active ? 'bg-white/30 text-rose-700' : 'text-slate-600 dark:text-slate-200', 'rounded-full text-[11px]')}
                        >
                          {tab.badge}
                        </Badge>
                      ) : null}
                    </Link>
                  );
                })}
              </div>
            </SheetContent>
          </Sheet>
        </div>
      </div>
    </div>
  );
}

function TenantMobileNav({
  items,
  onPrefetch,
}: {
  items: NavItem[];
  onPrefetch: (path: string) => void;
}) {
  const { t } = useTranslation('common');

  return (
    <nav className="md:hidden" aria-label={t('navigation.mobile', { defaultValue: 'Tenant Navigation' })}>
      <div
        aria-hidden
        className="pointer-events-none fixed inset-x-0 bottom-0 z-30 h-12 bg-gradient-to-t from-white via-white/40 to-transparent dark:from-slate-950 dark:via-slate-950/60 dark:to-transparent"
      />
      <div className="fixed inset-x-0 bottom-0 z-40 border-t border-slate-200/80 bg-white/95 px-4 pb-[calc(env(safe-area-inset-bottom,0)+0.75rem)] pt-3 shadow-2xl shadow-rose-300/15 backdrop-blur supports-[backdrop-filter]:bg-white/90 dark:border-slate-800/70 dark:bg-slate-950/90">
        <div className="mx-auto flex max-w-xl items-center justify-around gap-1">
          {items.map((item) => (
            <NavLink
              key={item.key}
              to={item.to}
              end={item.end}
              onPointerEnter={() => onPrefetch(item.prefetchKey ?? item.to)}
              onFocus={() => onPrefetch(item.prefetchKey ?? item.to)}
              onTouchStart={() => onPrefetch(item.prefetchKey ?? item.to)}
              className={({ isActive }) =>
                cn(
                  'flex flex-col items-center gap-1 rounded-xl px-3 py-2 text-xs font-semibold text-slate-600 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-rose-300 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:text-slate-300 dark:focus-visible:ring-offset-slate-950',
                  isActive
                    ? 'bg-rose-600 text-white shadow-md shadow-rose-400/25'
                    : cn(
                        item.highlight
                          ? 'text-rose-600 dark:text-rose-200'
                          : 'text-slate-600 dark:text-slate-300',
                        'hover:text-rose-700 dark:hover:text-rose-200'
                      )
                )
              }
            >
              <item.icon className="h-5 w-5" />
              <span>{item.label}</span>
            </NavLink>
          ))}
        </div>
      </div>
    </nav>
  );
}

