import { Link, NavLink, Outlet, useLocation, useNavigate, useSearchParams } from 'react-router-dom';
import { useEffect, useState, useCallback, useRef } from 'react';
import {
  LayoutDashboard, Users, Sparkles, MailX, Search, RefreshCw, LogOut,
  ChevronLeft, ChevronRight, ChevronDown, X, Plus, Wand2, ShieldCheck,
  ScrollText, ListChecks,
} from 'lucide-react';
import { AuthApi, SyncApi, AnalyticsApi } from '../api/client.js';
import Logo from './Logo.jsx';
import DevBanner from './DevBanner.jsx';
import SyncStatus from './SyncStatus.jsx';
import DigestToggle from './DigestToggle.jsx';
import useSavedSearches from '../hooks/useSavedSearches.js';
import { cn } from '../lib/utils.js';
import {
  Button, Input, Separator, ThemeToggle, Tooltip, TooltipContent, TooltipTrigger,
  DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem,
  DropdownMenuLabel, DropdownMenuSeparator,
} from './ui';

// ── Folder definitions ────────────────────────────────────────────────────────

const MAILBOX = [
  { slug: 'inbox',     icon: '📥', label: 'Inbox',      countKey: 'inbox' },
  { slug: 'allmail',   icon: '📬', label: 'All Mail',   countKey: 'allMail' },
  { slug: 'starred',   icon: '⭐', label: 'Starred',    countKey: 'starred' },
  { slug: 'sent',      icon: '📤', label: 'Sent',       countKey: 'sent' },
  { slug: 'drafts',    icon: '✏️',  label: 'Drafts',     countKey: 'drafts' },
  { slug: 'archive',   icon: '📦', label: 'Archive',    countKey: null },
  { slug: 'spam',      icon: '🚫', label: 'Spam',       countKey: 'spam' },
  { slug: 'trash',     icon: '🗑️',  label: 'Trash',      countKey: 'trash' },
  { slug: 'unlabeled', icon: '🏷️',  label: 'Unlabeled',  countKey: null },
  { slug: 'pinned',    icon: '📌', label: 'Pinned',     countKey: null },
  { slug: 'readlater', icon: '🔖', label: 'Read Later', countKey: null },
];

const FAV_SPECIALS = {
  inbox:     { slug: 'inbox',     icon: '📥', label: 'Inbox',       countKey: 'inbox',  type: 'mailbox' },
  unread:    { slug: 'unread',    icon: '🔵', label: 'Unread Mail', countKey: 'unread', type: 'filter' },
  large:     { slug: 'large',     icon: '📎', label: 'Large Mail',  countKey: 'large',  type: 'filter' },
  old:       { slug: 'old',       icon: '🕰️',  label: 'Old Mail',   countKey: 'old',    type: 'filter' },
  readlater: { slug: 'readlater', icon: '🔖', label: 'Read Later',  countKey: null,     type: 'filter' },
};

const DEFAULT_FAV_SLUGS = ['inbox', 'unread', 'large', 'old', 'readlater'];

const SMART_FOLDERS = [
  { slug: 'automated',    icon: '🤖', label: 'Automated',           countKey: 'automated' },
  { slug: 'noreply',      icon: '🔇', label: 'No-Reply',             countKey: 'noreply' },
  { slug: 'shopping',     icon: '🛍️',  label: 'Online Shopping',     countKey: 'shopping' },
  { slug: 'gaming',       icon: '🎮', label: 'Gaming',               countKey: 'gaming' },
  { slug: 'finance',      icon: '💳', label: 'Finance & Insurance',  countKey: 'finance' },
  { slug: 'sales',        icon: '🏷️',  label: 'Seasonal Sales',      countKey: 'sales' },
  { slug: 'ridesharing',  icon: '🚗', label: 'Ride Sharing',         countKey: 'ridesharing' },
  { slug: 'food',         icon: '🍕', label: 'Food Delivery',        countKey: 'food' },
  { slug: 'social',       icon: '📱', label: 'Social Notifications', countKey: 'social' },
  { slug: 'wellness',     icon: '🏃', label: 'Wellness & Sport',     countKey: 'wellness' },
  { slug: 'travel',       icon: '✈️',  label: 'Travel',               countKey: 'travel' },
  { slug: 'subscriptions',icon: '🔄', label: 'Subscriptions & SaaS', countKey: 'subscriptions' },
  { slug: 'parcels',      icon: '📦', label: 'Parcels & Delivery',   countKey: 'parcels' },
  { slug: 'recruitment',  icon: '💼', label: 'Recruitment & Jobs',   countKey: 'recruitment' },
  { slug: 'events',       icon: '🎟️',  label: 'Events & Tickets',    countKey: 'events' },
  { slug: 'security',     icon: '🔐', label: 'Security & Alerts',    countKey: 'security' },
  { slug: 'healthcare',   icon: '🏥', label: 'Healthcare',           countKey: 'healthcare' },
  { slug: 'education',    icon: '🎓', label: 'Education',            countKey: 'education' },
  { slug: 'news',         icon: '📰', label: 'News & Media',         countKey: 'news' },
  { slug: 'property',     icon: '🏠', label: 'Property & Utilities', countKey: 'property' },
  { slug: 'charity',      icon: '❤️',  label: 'Charities',           countKey: 'charity' },
  { slug: 'government',   icon: '🏛️',  label: 'Government',          countKey: 'government' },
  { slug: 'crypto',       icon: '📈', label: 'Crypto & Investing',   countKey: 'crypto' },
  { slug: 'family',       icon: '👨‍👩‍👧', label: 'Family & School',     countKey: 'family' },
];

// Primary app navigation (top of the sidebar). Automation pages are placeholders
// until their feature work lands (see docs/specs); links are kept here so the IA
// is visible, and they no-op gracefully to routes added later.
const PRIMARY_NAV = [
  { to: '/app',             label: 'Dashboard',   icon: LayoutDashboard, end: true },
  { to: '/app/senders',     label: 'Senders',     icon: Users },
  { to: '/app/cleanup',     label: 'Cleanup',     icon: Sparkles },
  { to: '/app/unsubscribe', label: 'Unsubscribe', icon: MailX },
];

// ── Helpers ───────────────────────────────────────────────────────────────────

const fmtCount = (n) => {
  if (!n) return null;
  return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
};

const LS_FAV   = 'ii:fav-slugs';
const LS_OPEN  = 'ii:sidebar-open';
const LS_SECTS = 'ii:sidebar-sections';

const loadFavs = () => {
  try { return JSON.parse(localStorage.getItem(LS_FAV)) ?? DEFAULT_FAV_SLUGS; }
  catch { return DEFAULT_FAV_SLUGS; }
};
const saveFavs = (v) => localStorage.setItem(LS_FAV, JSON.stringify(v));

const loadSections = () => {
  try { return JSON.parse(localStorage.getItem(LS_SECTS)) ?? { fav: true, mailbox: true, smart: true, saved: true }; }
  catch { return { fav: true, mailbox: true, smart: true, saved: true }; }
};
const saveSections = (v) => localStorage.setItem(LS_SECTS, JSON.stringify(v));

// ── Sidebar sub-components ──────────────────────────────────────────────────────

function SectionHead({ label, open, onToggle, collapsed }) {
  if (collapsed) return <Separator className="my-2" />;
  return (
    <button
      onClick={onToggle}
      className="flex w-full items-center justify-between px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground/80 transition-colors hover:text-muted-foreground"
    >
      <span>{label}</span>
      <ChevronDown className={cn('h-3.5 w-3.5 transition-transform', !open && '-rotate-90')} />
    </button>
  );
}

function FolderRow({ item, active, count, collapsed, extra }) {
  const content = (
    <Link
      to={`/app/folder/${item.slug}`}
      className={cn(
        'group flex items-center gap-2.5 rounded-md px-3 py-1.5 text-sm transition-colors',
        collapsed && 'justify-center px-0',
        active ? 'bg-primary/10 font-medium text-primary' : 'text-foreground/80 hover:bg-muted'
      )}
    >
      <span className="text-base leading-none">{item.icon}</span>
      {!collapsed && (
        <>
          <span className="flex-1 truncate">{item.label}</span>
          {count && <span className="text-xs tabular-nums text-muted-foreground">{count}</span>}
          {extra}
        </>
      )}
    </Link>
  );
  if (collapsed) {
    return (
      <Tooltip>
        <TooltipTrigger asChild>{content}</TooltipTrigger>
        <TooltipContent side="right">{item.label}</TooltipContent>
      </Tooltip>
    );
  }
  return content;
}

// ── Main Layout ───────────────────────────────────────────────────────────────

export default function Layout() {
  const [user, setUser] = useState(null);
  const [searchParams] = useSearchParams();
  const [searchQuery, setSearchQuery] = useState(() => searchParams.get('q') ?? '');
  const [sidebarOpen, setSidebarOpen] = useState(() => {
    try { return localStorage.getItem(LS_OPEN) !== 'false'; } catch { return true; }
  });
  const [sections, setSections] = useState(loadSections);
  const [favSlugs, setFavSlugs] = useState(loadFavs);
  const [counts, setCounts] = useState(null);
  const { searches: savedSearches, remove: removeSavedSearch } = useSavedSearches();

  const loc = useLocation();
  const navigate = useNavigate();
  const searchInputRef = useRef(null);
  const collapsed = !sidebarOpen;

  useEffect(() => { AuthApi.me().then(setUser).catch(() => {}); }, []);
  useEffect(() => { AnalyticsApi.sidebarCounts().then(setCounts).catch(() => {}); }, []);

  // "/" focuses the search bar from anywhere, unless already typing in a field.
  useEffect(() => {
    const handler = (e) => {
      if (e.key !== '/') return;
      const tag = document.activeElement?.tagName;
      if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
      e.preventDefault();
      searchInputRef.current?.focus();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, []);

  const toggleSidebar = () => {
    setSidebarOpen((o) => { localStorage.setItem(LS_OPEN, String(!o)); return !o; });
  };

  const toggleSection = (key) => {
    setSections((s) => { const next = { ...s, [key]: !s[key] }; saveSections(next); return next; });
  };

  const toggleFav = useCallback((slug) => {
    setFavSlugs((prev) => {
      const next = prev.includes(slug) ? prev.filter((s) => s !== slug) : [...prev, slug];
      saveFavs(next);
      return next;
    });
  }, []);

  const activeSlug = loc.pathname.startsWith('/app/folder/')
    ? loc.pathname.split('/app/folder/')[1]
    : null;

  const logout = async () => {
    try { await AuthApi.logout(); } catch { /* ignore */ }
    navigate('/');
  };

  const submitSearch = (e) => {
    e.preventDefault();
    const q = searchQuery.trim();
    if (q) navigate(`/app/search?q=${encodeURIComponent(q)}`);
  };

  const startSync = async () => {
    try { await SyncApi.incremental(); } catch { /* ignore */ }
    if (loc.pathname !== '/app') navigate('/app');
    window.dispatchEvent(new Event('inboxintel:sync-started'));
  };

  const mailboxCount = (item) => fmtCount(item.countKey ? counts?.[item.countKey] : null);
  const smartCount   = (item) => fmtCount(counts?.smartFolders?.[item.slug]);

  const favItems = favSlugs.map((slug) => {
    if (FAV_SPECIALS[slug]) return { ...FAV_SPECIALS[slug], source: 'special' };
    const sf = SMART_FOLDERS.find((f) => f.slug === slug);
    return sf ? { ...sf, source: 'smart' } : null;
  }).filter(Boolean);

  const favCount = (item) =>
    item.source === 'smart' ? smartCount(item) : fmtCount(item.countKey ? counts?.[item.countKey] : null);

  const sortedSmart = [...SMART_FOLDERS]
    .filter((f) => !counts || (counts.smartFolders?.[f.slug] ?? 0) > 0)
    .sort((a, b) => (counts?.smartFolders?.[b.slug] ?? 0) - (counts?.smartFolders?.[a.slug] ?? 0));

  const isPinnedSmart = (slug) => favSlugs.includes(slug);
  const userInitial = (user?.email?.[0] || '?').toUpperCase();

  return (
    <div className="flex h-screen flex-col bg-background text-foreground">
      <DevBanner />

      {/* ── Topbar ── */}
      <header className="z-30 flex h-14 shrink-0 items-center gap-3 border-b border-border bg-card/80 px-4 backdrop-blur">
        <Link to="/app" className="flex items-center gap-2 shrink-0">
          <Logo size={26} withWordmark />
        </Link>

        <form className="relative ml-2 hidden flex-1 md:block" onSubmit={submitSearch}>
          <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            ref={searchInputRef}
            type="search"
            placeholder="Search…  from:  is:unread  has:attachment    ( / )"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            aria-label="Search emails"
            className="max-w-xl pl-9"
          />
        </form>

        <div className="flex flex-1 items-center justify-end gap-1.5 md:flex-initial">
          <SyncStatus />
          <DigestToggle />
          <ThemeToggle />
          <Button onClick={startSync} size="sm" className="gap-1.5">
            <RefreshCw className="h-4 w-4" />
            <span className="hidden sm:inline">Sync now</span>
          </Button>
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <button
                className="ml-1 flex h-8 w-8 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                aria-label="Account menu"
              >
                {userInitial}
              </button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="min-w-[12rem]">
              <DropdownMenuLabel className="truncate normal-case">{user?.email || 'Signed in'}</DropdownMenuLabel>
              <DropdownMenuSeparator />
              <DropdownMenuItem onSelect={logout} className="text-danger focus:bg-danger/10">
                <LogOut className="h-4 w-4" /> Log out
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </header>

      <div className="flex flex-1 overflow-hidden">
        {/* ── Sidebar ── */}
        <aside
          className={cn(
            'flex shrink-0 flex-col overflow-y-auto border-r border-border bg-card transition-[width] duration-200',
            collapsed ? 'w-16' : 'w-64'
          )}
        >
          <nav className="flex flex-col gap-0.5 p-2">
            {PRIMARY_NAV.map((n) => {
              const Icon = n.icon;
              const link = (
                <NavLink
                  key={n.to}
                  to={n.to}
                  end={n.end}
                  className={({ isActive }) =>
                    cn(
                      'flex items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium transition-colors',
                      collapsed && 'justify-center px-0',
                      isActive ? 'bg-primary/10 text-primary' : 'text-foreground/80 hover:bg-muted'
                    )
                  }
                >
                  <Icon className="h-[18px] w-[18px] shrink-0" />
                  {!collapsed && <span>{n.label}</span>}
                </NavLink>
              );
              return collapsed ? (
                <Tooltip key={n.to}>
                  <TooltipTrigger asChild>{link}</TooltipTrigger>
                  <TooltipContent side="right">{n.label}</TooltipContent>
                </Tooltip>
              ) : link;
            })}
          </nav>

          <Separator />

          <div className="flex-1 p-2">
            {/* Favorites */}
            <SectionHead label="Favorites" open={sections.fav} onToggle={() => toggleSection('fav')} collapsed={collapsed} />
            {(sections.fav || collapsed) && (
              <div className="flex flex-col gap-0.5">
                {favItems.map((item) => (
                  <FolderRow
                    key={item.slug}
                    item={item}
                    active={activeSlug === item.slug}
                    count={favCount(item)}
                    collapsed={collapsed}
                    extra={item.source === 'smart' && (
                      <button
                        className="text-muted-foreground opacity-0 transition-opacity hover:text-danger group-hover:opacity-100"
                        title="Remove from Favorites"
                        onClick={(e) => { e.preventDefault(); toggleFav(item.slug); }}
                      ><X className="h-3.5 w-3.5" /></button>
                    )}
                  />
                ))}
              </div>
            )}

            {/* Saved Searches */}
            {savedSearches.length > 0 && (
              <>
                <SectionHead label="Saved Searches" open={sections.saved} onToggle={() => toggleSection('saved')} collapsed={collapsed} />
                {!collapsed && sections.saved && (
                  <div className="flex flex-col gap-0.5">
                    {savedSearches.map((s) => (
                      <div key={s.id} className="group flex items-center">
                        <Link
                          to={`/app/search?q=${encodeURIComponent(s.query)}`}
                          title={s.query}
                          className={cn(
                            'flex flex-1 items-center gap-2.5 rounded-md px-3 py-1.5 text-sm transition-colors',
                            loc.pathname === '/app/search' && searchParams.get('q') === s.query
                              ? 'bg-primary/10 font-medium text-primary'
                              : 'text-foreground/80 hover:bg-muted'
                          )}
                        >
                          <Search className="h-4 w-4 shrink-0 text-muted-foreground" />
                          <span className="flex-1 truncate">{s.label}</span>
                        </Link>
                        <button
                          className="px-1.5 text-muted-foreground opacity-0 transition-opacity hover:text-danger group-hover:opacity-100"
                          title="Remove saved search"
                          onClick={(e) => { e.preventDefault(); removeSavedSearch(s.id); }}
                        ><X className="h-3.5 w-3.5" /></button>
                      </div>
                    ))}
                  </div>
                )}
              </>
            )}

            {/* Mailbox */}
            <SectionHead label="Mailbox" open={sections.mailbox} onToggle={() => toggleSection('mailbox')} collapsed={collapsed} />
            {(sections.mailbox || collapsed) && (
              <div className="flex flex-col gap-0.5">
                {MAILBOX.map((item) => (
                  <FolderRow key={item.slug} item={item} active={activeSlug === item.slug} count={mailboxCount(item)} collapsed={collapsed} />
                ))}
              </div>
            )}

            {/* Smart Folders */}
            <SectionHead label="Smart Folders" open={sections.smart} onToggle={() => toggleSection('smart')} collapsed={collapsed} />
            {(sections.smart || collapsed) && (
              <div className="flex flex-col gap-0.5">
                {sortedSmart.map((item) => (
                  <FolderRow
                    key={item.slug}
                    item={item}
                    active={activeSlug === item.slug}
                    count={smartCount(item)}
                    collapsed={collapsed}
                    extra={
                      <button
                        className={cn(
                          'text-muted-foreground transition-opacity hover:text-primary',
                          isPinnedSmart(item.slug) ? 'opacity-0 hover:text-danger group-hover:opacity-100' : 'opacity-0 group-hover:opacity-100'
                        )}
                        title={isPinnedSmart(item.slug) ? 'Remove from Favorites' : 'Add to Favorites'}
                        onClick={(e) => { e.preventDefault(); toggleFav(item.slug); }}
                      >{isPinnedSmart(item.slug) ? <X className="h-3.5 w-3.5" /> : <Plus className="h-3.5 w-3.5" />}</button>
                    }
                  />
                ))}
              </div>
            )}
          </div>

          {/* Collapse toggle */}
          <div className="border-t border-border p-2">
            <Button variant="ghost" size={collapsed ? 'icon' : 'sm'} onClick={toggleSidebar} className={cn('w-full', collapsed && 'w-auto')}>
              {collapsed ? <ChevronRight className="h-4 w-4" /> : <><ChevronLeft className="h-4 w-4" /> Collapse</>}
            </Button>
          </div>
        </aside>

        {/* ── Main content ── */}
        <main className="flex-1 overflow-y-auto">
          <div className="mx-auto max-w-7xl p-6 lg:p-8">
            <Outlet />
          </div>
        </main>
      </div>
    </div>
  );
}
