import { useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { loadHelpSections } from '../lib/help-content';
import { filterSections, renderHelpHtml, type HelpCategory, type HelpSection } from '../lib/help';

const CATEGORY_LABEL_KEY: Record<HelpCategory, string> = {
  basic: 'category.basic',
  advanced: 'category.advanced',
  admin: 'category.admin',
};
const CATEGORY_ORDER: HelpCategory[] = ['basic', 'advanced', 'admin'];

interface HelpPageProps {
  isAdmin: boolean;
  onAskAi: () => void;
  /** Currently selected section id (from URL). */
  selectedId?: string;
  /** Called when the user picks a section; caller writes it to the URL. */
  onSelect: (id: string) => void;
}

export function HelpPage({ isAdmin, onAskAi, selectedId, onSelect }: HelpPageProps) {
  const { t } = useTranslation('help');
  const all = useMemo(() => loadHelpSections(), []);
  const visible = useMemo(
    () => all.filter((s) => s.category !== 'admin' || isAdmin),
    [all, isAdmin],
  );
  const [query, setQuery] = useState('');
  const mainRef = useRef<HTMLElement>(null);

  const filtered = useMemo(() => filterSections(visible, query), [visible, query]);
  const selected: HelpSection | undefined =
    visible.find((s) => s.id === selectedId) ?? visible[0];
  const rendered = useMemo(
    () => (selected ? renderHelpHtml(selected.body) : { html: '', headings: [] }),
    [selected],
  );

  const categories = CATEGORY_ORDER.filter((c) => c !== 'admin' || isAdmin);

  function scrollToHeading(id: string) {
    const el = mainRef.current?.querySelector(`#${CSS.escape(id)}`);
    el?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  }

  function handleContentClick(e: React.MouseEvent<HTMLElement>) {
    const a = (e.target as HTMLElement).closest('a');
    if (!a) return;
    const href = a.getAttribute('href');
    if (!href) return;
    if (href.startsWith('#')) {
      e.preventDefault();
      scrollToHeading(decodeURIComponent(href.slice(1)));
      return;
    }
    const m = /^\.\/\d+-(.+?)\.md(?:#.*)?$/.exec(href);
    if (m) {
      const id = m[1];
      if (all.some((s) => s.id === id)) {
        e.preventDefault();
        onSelect(id);
      }
    }
  }

  return (
    <div className="flex h-full overflow-hidden bg-surface">
      {/* Left: TOC */}
      <aside className="w-72 shrink-0 border-r border-hairline bg-canvas overflow-y-auto flex flex-col">
        <div className="p-4 border-b border-hairline">
          <h2 className="text-sm font-semibold text-slate-900 m-0">{t('title')}</h2>
          <button
            type="button"
            onClick={onAskAi}
            className="mt-3 w-full px-3 py-2 rounded-md text-xs font-semibold bg-accent text-accent-fg hover:bg-accent-deep transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-ring"
          >
            {t('askAi')}
          </button>
          <p className="mt-2 text-2xs text-slate-500 leading-relaxed">
            {t('askAiHint')}
          </p>
          <input
            type="search"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder={t('searchPlaceholder')}
            className="mt-3 w-full px-2.5 py-1.5 rounded border border-hairline text-[13px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-ring"
            aria-label={t('searchAria')}
          />
        </div>
        <nav className="p-3 flex-1 min-h-0 overflow-y-auto" aria-label={t('tocAria')}>
          {filtered.length === 0 && (
            <p className="px-2 py-2 text-xs text-slate-500">{t('noResults', { query })}</p>
          )}
          {categories.map((cat) => {
            const items = filtered.filter((s) => s.category === cat);
            if (items.length === 0) return null;
            return (
              <div key={cat} className="mb-3">
                <div className="px-2 py-1 text-[10px] uppercase tracking-wide text-slate-500 font-semibold">
                  {t(CATEGORY_LABEL_KEY[cat])}
                </div>
                {items.map((s) => (
                  <button
                    key={s.id}
                    type="button"
                    onClick={() => onSelect(s.id)}
                    aria-current={selected?.id === s.id ? 'page' : undefined}
                    className={`block w-full text-left px-2 py-1.5 rounded text-[13px] mb-0.5 transition-colors ${
                      selected?.id === s.id
                        ? 'bg-accent-soft text-accent font-semibold'
                        : 'text-slate-700 hover:bg-surface'
                    }`}
                  >
                    {s.title}
                  </button>
                ))}
              </div>
            );
          })}
        </nav>
      </aside>

      {/* Right: rendered markdown + heading nav */}
      <main ref={mainRef} className="flex-1 min-w-0 overflow-y-auto bg-canvas">
        <div className="flex max-w-5xl mx-auto px-8 py-8 gap-8">
          <article
            className="prose prose-sm dark:prose-invert flex-1 min-w-0"
            onClick={handleContentClick}
            dangerouslySetInnerHTML={{ __html: rendered.html }}
          />
          {rendered.headings.length > 1 && (
            <nav className="hidden xl:block w-48 shrink-0 sticky top-8 self-start" aria-label={t('sectionTocAria')}>
              <div className="text-[10px] uppercase tracking-wide text-slate-500 font-semibold mb-2">
                {t('thisPage')}
              </div>
              {rendered.headings.map((h) => (
                <button
                  key={h.id}
                  type="button"
                  onClick={() => scrollToHeading(h.id)}
                  className={`block w-full text-left py-0.5 text-[12px] text-slate-600 hover:text-accent ${
                    h.depth === 3 ? 'pl-3' : ''
                  }`}
                >
                  {h.text}
                </button>
              ))}
            </nav>
          )}
        </div>
      </main>
    </div>
  );
}
