'use client';

import { useEffect, useRef, useState } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import {
  ChevronDown,
  Cloud,
  FileText,
  History,
  KeyRound,
  LayoutDashboard,
  LogOut,
  MapPin,
  Menu,
  NotebookText,
  Package,
  PencilLine,
  Shield,
  Sprout,
  Tractor,
  Truck,
  Upload,
  Construction,
  Wheat,
  X,
  type LucideIcon,
} from 'lucide-react';

import { logout } from '@/lib/api';

type NavItem = {
  label: string;
  href: string;
  icon?: LucideIcon;
  match?: (pathname: string) => boolean;
};

type NavGroup = {
  key: string;
  label: string;
  type: 'link' | 'group';
  href?: string;
  icon?: LucideIcon;
  items?: NavItem[];
};

const matchesHref = (pathname: string, href: string) =>
  pathname === href || pathname.startsWith(`${href}/`);

const navGroups: NavGroup[] = [
  {
    key: 'home',
    label: 'ホーム',
    type: 'link',
    href: '/dashboard',
    icon: LayoutDashboard,
  },
  {
    key: 'planning',
    label: '計画',
    type: 'group',
    icon: Wheat,
    items: [
      { label: '作付け計画', href: '/allocation', icon: Wheat },
      {
        label: '施肥計画',
        href: '/fertilizer',
        icon: Sprout,
        match: (pathname) =>
          matchesHref(pathname, '/fertilizer') &&
          !matchesHref(pathname, '/fertilizer/spreading') &&
          !matchesHref(pathname, '/fertilizer/masters'),
      },
      { label: '田植え計画', href: '/rice-transplant', icon: Tractor },
      { label: '運搬計画', href: '/distribution', icon: Truck },
    ],
  },
  {
    key: 'records',
    label: '実績',
    type: 'group',
    icon: NotebookText,
    items: [
      {
        label: '散布実績',
        href: '/fertilizer/spreading',
        icon: PencilLine,
      },
      { label: '畔塗記録', href: '/levee-work', icon: Construction },
      { label: '作業記録', href: '/workrecords', icon: NotebookText },
    ],
  },
  {
    key: 'masters',
    label: 'マスター',
    type: 'group',
    icon: Package,
    items: [
      { label: '圃場管理', href: '/fields', icon: MapPin },
      {
        label: '資材マスタ',
        href: '/materials/masters',
        icon: Package,
      },
      {
        label: '肥料マスタ',
        href: '/fertilizer/masters',
        icon: Sprout,
      },
    ],
  },
  {
    key: 'support',
    label: '帳票・連携',
    type: 'group',
    icon: FileText,
    items: [
      {
        label: '在庫管理',
        href: '/materials',
        icon: Package,
        match: (pathname) =>
          matchesHref(pathname, '/materials') && !matchesHref(pathname, '/materials/masters'),
      },
      { label: '帳票出力', href: '/reports', icon: FileText },
      { label: 'データ取込', href: '/import', icon: Upload },
      { label: '気象', href: '/weather', icon: Cloud },
      { label: 'メール履歴', href: '/mail/history', icon: History },
      { label: 'メールルール', href: '/mail/rules', icon: Shield },
    ],
  },
];

const userActions: NavItem[] = [
  { label: 'パスワード変更', href: '/settings/password', icon: KeyRound },
];

export default function Navbar() {
  const router = useRouter();
  const pathname = usePathname();
  const navRef = useRef<HTMLElement>(null);
  const [openDesktopGroup, setOpenDesktopGroup] = useState<string | null>(null);
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  const [openMobileGroups, setOpenMobileGroups] = useState<string[]>([]);

  useEffect(() => {
    const handlePointerDown = (event: MouseEvent) => {
      if (!navRef.current?.contains(event.target as Node)) {
        setOpenDesktopGroup(null);
      }
    };

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setOpenDesktopGroup(null);
        setMobileMenuOpen(false);
      }
    };

    document.addEventListener('mousedown', handlePointerDown);
    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('mousedown', handlePointerDown);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, []);

  useEffect(() => {
    setOpenDesktopGroup(null);
    setMobileMenuOpen(false);
    setOpenMobileGroups((prev) => {
      const activeKey = getActiveGroupKey(pathname);
      if (!activeKey) return prev;
      return prev.includes(activeKey) ? prev : [activeKey];
    });
  }, [pathname]);

  const handleLogout = () => {
    logout();
  };

  const navigateTo = (href: string) => {
    setOpenDesktopGroup(null);
    setMobileMenuOpen(false);
    router.push(href);
  };

  const toggleDesktopGroup = (key: string) => {
    setOpenDesktopGroup((prev) => (prev === key ? null : key));
  };

  const toggleMobileGroup = (key: string) => {
    setOpenMobileGroups((prev) =>
      prev.includes(key) ? prev.filter((groupKey) => groupKey !== key) : [...prev, key]
    );
  };

  const toggleMobileMenu = () => {
    if (!mobileMenuOpen) {
      const activeKey = getActiveGroupKey(pathname);
      setOpenMobileGroups(activeKey ? [activeKey] : []);
    }
    setMobileMenuOpen((prev) => !prev);
  };

  return (
    <nav ref={navRef} className="border-b border-gray-200 bg-white shadow-sm">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <div className="flex h-16 items-center justify-between">
          <div className="flex items-center gap-4 lg:gap-8">
            <button
              onClick={() => navigateTo('/dashboard')}
              className="text-lg font-bold text-green-700 transition-colors hover:text-green-800 sm:text-xl"
            >
              KeinaSystem
            </button>

            <div className="hidden items-center gap-2 lg:flex">
              {navGroups.map((group) =>
                group.type === 'link' ? (
                  <DesktopLinkButton
                    key={group.key}
                    group={group}
                    pathname={pathname}
                    onNavigate={navigateTo}
                  />
                ) : (
                  <DesktopGroupButton
                    key={group.key}
                    group={group}
                    isOpen={openDesktopGroup === group.key}
                    pathname={pathname}
                    onNavigate={navigateTo}
                    onToggle={toggleDesktopGroup}
                  />
                )
              )}
            </div>
          </div>

          <div className="hidden items-center gap-1 lg:flex">
            {userActions.map((item) => (
              <button
                key={item.href}
                onClick={() => navigateTo(item.href)}
                className={`rounded-md px-3 py-2 text-sm transition-colors ${
                  isItemActive(item, pathname)
                    ? 'bg-green-50 text-green-700'
                    : 'text-gray-500 hover:bg-gray-100 hover:text-gray-700'
                }`}
                title={item.label}
              >
                {item.icon ? <item.icon className="h-4 w-4" /> : item.label}
              </button>
            ))}
            <button
              onClick={handleLogout}
              className="flex items-center rounded-md px-4 py-2 text-sm text-gray-700 transition-colors hover:bg-gray-100 hover:text-gray-900"
            >
              <LogOut className="mr-2 h-4 w-4" />
              ログアウト
            </button>
          </div>

          <div className="flex items-center gap-2 lg:hidden">
            <button
              onClick={() => navigateTo('/settings/password')}
              className={`rounded-md p-2 transition-colors ${
                isItemActive(userActions[0], pathname)
                  ? 'bg-green-50 text-green-700'
                  : 'text-gray-500 hover:bg-gray-100 hover:text-gray-700'
              }`}
              title="パスワード変更"
            >
              <KeyRound className="h-5 w-5" />
            </button>
            <button
              onClick={toggleMobileMenu}
              className="rounded-md p-2 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900"
              aria-expanded={mobileMenuOpen}
              aria-label="メニューを開く"
            >
              {mobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
            </button>
          </div>
        </div>

        {mobileMenuOpen && (
          <div className="border-t border-gray-200 py-3 lg:hidden">
            <div className="space-y-1">
              {navGroups.map((group) =>
                group.type === 'link' ? (
                  <MobileLinkButton
                    key={group.key}
                    group={group}
                    pathname={pathname}
                    onNavigate={navigateTo}
                  />
                ) : (
                  <MobileGroupButton
                    key={group.key}
                    group={group}
                    isOpen={openMobileGroups.includes(group.key)}
                    pathname={pathname}
                    onNavigate={navigateTo}
                    onToggle={toggleMobileGroup}
                  />
                )
              )}
              <button
                onClick={handleLogout}
                className="mt-3 flex w-full items-center rounded-lg px-3 py-3 text-sm text-gray-700 transition-colors hover:bg-gray-100 hover:text-gray-900"
              >
                <LogOut className="mr-3 h-4 w-4" />
                ログアウト
              </button>
            </div>
          </div>
        )}
      </div>
    </nav>
  );
}

function DesktopLinkButton({
  group,
  pathname,
  onNavigate,
}: {
  group: NavGroup;
  pathname: string;
  onNavigate: (href: string) => void;
}) {
  const active = isGroupActive(group, pathname);
  const Icon = group.icon;

  return (
    <button
      onClick={() => group.href && onNavigate(group.href)}
      className={`flex items-center rounded-md px-3 py-2 text-sm transition-colors ${
        active ? 'bg-green-50 text-green-700' : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
      }`}
    >
      {Icon ? <Icon className="mr-2 h-4 w-4" /> : null}
      {group.label}
    </button>
  );
}

function DesktopGroupButton({
  group,
  isOpen,
  pathname,
  onNavigate,
  onToggle,
}: {
  group: NavGroup;
  isOpen: boolean;
  pathname: string;
  onNavigate: (href: string) => void;
  onToggle: (key: string) => void;
}) {
  const active = isGroupActive(group, pathname);
  const Icon = group.icon;

  return (
    <div className="relative">
      <button
        onClick={() => onToggle(group.key)}
        className={`flex items-center rounded-md px-3 py-2 text-sm transition-colors ${
          active || isOpen
            ? 'bg-green-50 text-green-700'
            : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
        }`}
        aria-expanded={isOpen}
      >
        {Icon ? <Icon className="mr-2 h-4 w-4" /> : null}
        {group.label}
        <ChevronDown className={`ml-2 h-4 w-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} />
      </button>

      {isOpen && group.items ? (
        <div className="absolute left-0 top-full z-20 mt-2 w-64 rounded-xl border border-gray-200 bg-white p-2 shadow-lg">
          {group.items.map((item) => (
            <button
              key={item.href}
              onClick={() => onNavigate(item.href)}
              className={`flex w-full items-center rounded-lg px-3 py-2 text-left text-sm transition-colors ${
                isItemActive(item, pathname)
                  ? 'bg-green-50 text-green-700'
                  : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
              }`}
            >
              {item.icon ? <item.icon className="mr-3 h-4 w-4" /> : null}
              {item.label}
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}

function MobileLinkButton({
  group,
  pathname,
  onNavigate,
}: {
  group: NavGroup;
  pathname: string;
  onNavigate: (href: string) => void;
}) {
  const active = isGroupActive(group, pathname);
  const Icon = group.icon;

  return (
    <button
      onClick={() => group.href && onNavigate(group.href)}
      className={`flex w-full items-center rounded-lg px-3 py-3 text-left text-sm transition-colors ${
        active ? 'bg-green-50 text-green-700' : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
      }`}
    >
      {Icon ? <Icon className="mr-3 h-4 w-4" /> : null}
      {group.label}
    </button>
  );
}

function MobileGroupButton({
  group,
  isOpen,
  pathname,
  onNavigate,
  onToggle,
}: {
  group: NavGroup;
  isOpen: boolean;
  pathname: string;
  onNavigate: (href: string) => void;
  onToggle: (key: string) => void;
}) {
  const active = isGroupActive(group, pathname);
  const Icon = group.icon;

  return (
    <div className="rounded-lg border border-gray-200">
      <button
        onClick={() => onToggle(group.key)}
        className={`flex w-full items-center justify-between rounded-lg px-3 py-3 text-left text-sm transition-colors ${
          active || isOpen
            ? 'bg-green-50 text-green-700'
            : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
        }`}
        aria-expanded={isOpen}
      >
        <span className="flex items-center">
          {Icon ? <Icon className="mr-3 h-4 w-4" /> : null}
          {group.label}
        </span>
        <ChevronDown className={`h-4 w-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} />
      </button>

      {isOpen && group.items ? (
        <div className="space-y-1 border-t border-gray-200 px-2 py-2">
          {group.items.map((item) => (
            <button
              key={item.href}
              onClick={() => onNavigate(item.href)}
              className={`flex w-full items-center rounded-lg px-3 py-2.5 text-left text-sm transition-colors ${
                isItemActive(item, pathname)
                  ? 'bg-green-50 text-green-700'
                  : 'text-gray-700 hover:bg-gray-100 hover:text-gray-900'
              }`}
            >
              {item.icon ? <item.icon className="mr-3 h-4 w-4" /> : null}
              {item.label}
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}

function isGroupActive(group: NavGroup, pathname: string) {
  if (group.type === 'link') {
    return group.href ? matchesHref(pathname, group.href) : false;
  }

  return group.items?.some((item) => isItemActive(item, pathname)) ?? false;
}

function isItemActive(item: NavItem, pathname: string) {
  if (item.match) {
    return item.match(pathname);
  }
  return matchesHref(pathname, item.href);
}

function getActiveGroupKey(pathname: string) {
  return navGroups.find((group) => isGroupActive(group, pathname))?.key ?? null;
}
