import { useCallback, useState } from 'react';
import { Outlet, Link, NavLink, useMatches } from 'react-router';
import { useTranslation } from 'react-i18next';
import { useTheme } from '../../contexts/ThemeContext';
import styles from './app-shell.module.css';

const SIDEBAR_COLLAPSED_KEY = 'appShell.sidebar.collapsed';

function readSidebarCollapsed(): boolean {
  try {
    return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === 'true';
  } catch {
    return false;
  }
}

function writeSidebarCollapsed(value: boolean): void {
  try {
    localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(value));
  } catch {
    /* ignore quota / disabled storage */
  }
}

interface CrumbHandle {
  crumb?: string | ((data: unknown) => string);
}

interface MatchWithHandle {
  handle?: CrumbHandle;
  data?: unknown;
  pathname: string;
}

export function AppShell() {
  const { t, i18n } = useTranslation();
  const { theme, toggleTheme } = useTheme();
  const matches = useMatches() as MatchWithHandle[];

  const [sidebarCollapsed, setSidebarCollapsed] = useState<boolean>(() =>
    readSidebarCollapsed(),
  );
  const toggleSidebar = useCallback(() => {
    setSidebarCollapsed((prev) => {
      const next = !prev;
      writeSidebarCollapsed(next);
      return next;
    });
  }, []);

  const crumbs = matches
    .filter((m) => m.handle?.crumb)
    .map((m) => {
      const raw =
        typeof m.handle!.crumb === 'function'
          ? m.handle!.crumb(m.data)
          : m.handle!.crumb!;
      // Resolve i18n key if it looks like a translation key (contains a dot)
      const label = raw.includes('.') ? t(raw) : raw;
      return { label, path: m.pathname };
    });

  const toggleLanguage = () => {
    const nextLng = i18n.language.startsWith('ru') ? 'en' : 'ru';
    i18n.changeLanguage(nextLng);
  };

  return (
    <div className={styles.shell}>
      {/* Header */}
      <header className={styles.header}>
        <Link to="/" className={styles.logo}>
          <span className={styles.logoIcon}>H</span>
          {t('app.title')}
        </Link>

        {crumbs.length > 0 && (
          <nav className={styles.breadcrumbs} aria-label="Breadcrumbs">
            {crumbs.map((crumb, index) => {
              const isLast = index === crumbs.length - 1;
              return (
                <span key={crumb.path} style={{ display: 'contents' }}>
                  {index > 0 && (
                    <span className={styles.breadcrumbSep} aria-hidden="true">
                      /
                    </span>
                  )}
                  {isLast ? (
                    <span className={styles.breadcrumbCurrent}>
                      {crumb.label}
                    </span>
                  ) : (
                    <Link to={crumb.path} className={styles.breadcrumbLink}>
                      {crumb.label}
                    </Link>
                  )}
                </span>
              );
            })}
          </nav>
        )}

        <div className={styles.headerSpacer} />

        <div className={styles.headerActions}>
          <button
            className={styles.headerBtn}
            onClick={toggleLanguage}
            title={t('language.toggle')}
            type="button"
          >
            {i18n.language.startsWith('ru') ? 'EN' : 'RU'}
          </button>
          <button
            className={styles.headerBtn}
            onClick={toggleTheme}
            title={t('theme.toggle')}
            type="button"
          >
            {theme === 'dark' ? '\u2600' : '\u263E'}
          </button>
        </div>
      </header>

      {/* Body */}
      <div className={styles.body}>
        {/* Sidebar (desktop) */}
        <nav
          className={[
            styles.sidebar,
            sidebarCollapsed ? styles.sidebarCollapsed : undefined,
          ]
            .filter(Boolean)
            .join(' ')}
          aria-label="Main navigation"
        >
          <button
            type="button"
            className={styles.sidebarToggle}
            onClick={toggleSidebar}
            title={sidebarCollapsed ? t('nav.expand') : t('nav.collapse')}
            aria-label={sidebarCollapsed ? t('nav.expand') : t('nav.collapse')}
          >
            {sidebarCollapsed ? '\u25B6' : '\u25C0'}
          </button>
          <NavLink
            to="/"
            end
            className={({ isActive }) =>
              [styles.navItem, isActive ? styles.navItemActive : undefined]
                .filter(Boolean)
                .join(' ')
            }
            title={sidebarCollapsed ? t('nav.apartments') : undefined}
          >
            <span className={styles.navIcon} aria-hidden="true">&#9634;</span>
            <span className={styles.navLabel}>{t('nav.apartments')}</span>
          </NavLink>
        </nav>

        {/* Main content */}
        <main className={styles.content}>
          <div className={styles.contentInner}>
            <Outlet />
          </div>
        </main>
      </div>

      {/* Bottom nav (mobile) */}
      <nav className={styles.bottomNav} aria-label="Mobile navigation">
        <NavLink
          to="/"
          end
          className={({ isActive }) =>
            [
              styles.bottomNavItem,
              isActive ? styles.bottomNavItemActive : undefined,
            ]
              .filter(Boolean)
              .join(' ')
          }
        >
          <span className={styles.bottomNavIcon} aria-hidden="true">&#9634;</span>
          {t('nav.apartments')}
        </NavLink>
      </nav>
    </div>
  );
}
