'use client';

import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { ProjetoMenuFaIcon } from './ProjetoMenuFaIcon';
import { ProjetoPageIcon } from './ProjetoPageIcon';
import { ProjetoMenuBadge } from './ProjetoMenuBadge';
import { SidebarMenuIcon } from '../Sidebar/SidebarMenuIcon';
import { isAplicacaoReactTipologia } from '@/features/projetos/lib/resolveAplicacaoReactTipologiaCopy';
import { getProjetoSprintAtualHref } from './projetoMobileEssenciais';
import type { MenuGroupConfig, MenuItemConfig } from './projetoMenuTypes';
import {
    essenciaisToMenuNode,
    filterProjetoMenuPageResults,
    findActiveLocation,
    findActiveRootNode,
    flattenProjetoMenuNodes,
    groupsToMenuNodes,
    isProjetoMenuItemActive,
    nodeContainsActive,
    type ProjetoMenuFlatEntry,
    type ProjetoMenuNode,
} from './projetoMenuNavigation';
import styles from './ProjetoLayout.module.scss';

export interface ProjetoMenuDrawerNavProps {
    projetoId: string;
    currentPath: string;
    menuGroups: MenuGroupConfig[];
    essenciaisItems: MenuItemConfig[];
    categoriaCodigo?: string | null;
    open: boolean;
    onClose?: () => void;
    onDeleteProjeto: () => void;
}

function renderBadges(node: ProjetoMenuNode) {
    return (
        <>
            {node.new ? <ProjetoMenuBadge variant="new" /> : null}
            {node.emBreve ? <ProjetoMenuBadge variant="emBreve" /> : null}
            {node.badgeCount != null && node.badgeCount > 0 ? (
                <ProjetoMenuBadge variant="count" count={node.badgeCount} />
            ) : null}
        </>
    );
}

/**
 * Conteúdo hierárquico do drawer "Menu do projeto" (drill-down + busca global).
 * Padrão alinhado ao menu mobile do Sidebar (painéis + slide).
 */
export function ProjetoMenuDrawerNav({
    projetoId,
    currentPath,
    menuGroups,
    essenciaisItems,
    categoriaCodigo,
    open,
    onClose,
    onDeleteProjeto,
}: ProjetoMenuDrawerNavProps) {
    const router = useRouter();
    const [searchQuery, setSearchQuery] = useState('');
    const [drillStack, setDrillStack] = useState<ProjetoMenuNode[]>([]);
    const [viewportWidth, setViewportWidth] = useState(0);
    const viewportRef = useRef<HTMLDivElement | null>(null);
    const backButtonRef = useRef<HTMLButtonElement | null>(null);
    const prevDrillDepthRef = useRef(0);
    const contextualizedOpenRef = useRef(false);

    const tipologicalRoots = useMemo(() => groupsToMenuNodes(menuGroups), [menuGroups]);

    const rootNodes = useMemo(() => {
        const nodes: ProjetoMenuNode[] = [];
        const essenciais = essenciaisToMenuNode(essenciaisItems);
        if (essenciais) nodes.push(essenciais);
        nodes.push(...tipologicalRoots);
        return nodes;
    }, [tipologicalRoots, essenciaisItems]);

    const flatEntries = useMemo(() => flattenProjetoMenuNodes(rootNodes), [rootNodes]);

    const searchResults = useMemo(
        () => filterProjetoMenuPageResults(flatEntries, searchQuery),
        [flatEntries, searchQuery],
    );

    const isSearching = searchQuery.trim().length > 0;

    const location = useMemo(
        () => findActiveLocation(menuGroups, projetoId, currentPath),
        [menuGroups, projetoId, currentPath],
    );

    const measureViewport = useCallback(() => {
        const el = viewportRef.current;
        if (!el) return;
        setViewportWidth(el.clientWidth);
    }, []);

    useEffect(() => {
        if (!open) {
            contextualizedOpenRef.current = false;
            setSearchQuery('');
            return;
        }
        measureViewport();
        const el = viewportRef.current;
        if (!el || typeof ResizeObserver === 'undefined') return;
        const ro = new ResizeObserver(() => measureViewport());
        ro.observe(el);
        return () => ro.disconnect();
    }, [open, measureViewport]);

    // Ao abrir: contextualizar no grupo tipológico da página (não em Essenciais).
    useEffect(() => {
        if (!open) return;
        if (contextualizedOpenRef.current) return;
        contextualizedOpenRef.current = true;
        const activeRoot = findActiveRootNode(tipologicalRoots, projetoId, currentPath);
        if (activeRoot?.children?.length) {
            const match = rootNodes.find((n) => n.id === activeRoot.id) ?? activeRoot;
            setDrillStack([match]);
        } else {
            setDrillStack([]);
        }
    }, [open, tipologicalRoots, rootNodes, projetoId, currentPath]);

    useEffect(() => {
        const prev = prevDrillDepthRef.current;
        prevDrillDepthRef.current = drillStack.length;
        if (!open || isSearching) return;
        if (drillStack.length > prev) {
            const id = requestAnimationFrame(() => backButtonRef.current?.focus());
            return () => cancelAnimationFrame(id);
        }
    }, [drillStack.length, open, isSearching]);

    const drillIn = useCallback((node: ProjetoMenuNode) => {
        if (!node.children?.length) return;
        setDrillStack((prev) => [...prev, node]);
    }, []);

    const drillOut = useCallback(() => {
        setDrillStack((prev) => prev.slice(0, -1));
    }, []);

    const closeAndNavigate = useCallback(
        (route: string) => {
            onClose?.();
            if (route === '#') return;
            router.push(route);
        },
        [onClose, router],
    );

    const handleSearchSelect = useCallback(
        (entry: ProjetoMenuFlatEntry) => {
            const route = entry.node.route;
            if (!route || route === '#') return;
            setSearchQuery('');
            onClose?.();
            router.push(route);
        },
        [onClose, router],
    );

    const handleLeafActivate = useCallback(
        (node: ProjetoMenuNode) => {
            if (node.action === 'excluir-projeto') {
                onClose?.();
                onDeleteProjeto();
                return;
            }
            if (node.route) {
                closeAndNavigate(node.route);
            }
        },
        [closeAndNavigate, onClose, onDeleteProjeto],
    );

    const renderRow = (node: ProjetoMenuNode, depth: number, index: number) => {
        const hasChildren = Boolean(node.children?.length);
        const activeLeaf = isProjetoMenuItemActive(node.route, projetoId, currentPath);
        const activeBranch = hasChildren && nodeContainsActive(node, projetoId, currentPath);
        const isDanger = Boolean(node.danger);

        if (hasChildren) {
            return (
                <li key={`${node.id}-${depth}-${index}`}>
                    <button
                        type="button"
                        className={`${styles.drawerDrillBtn} ${activeBranch ? styles.drawerDrillBtnActive : ''}`}
                        onClick={() => drillIn(node)}
                        aria-haspopup="true"
                    >
                        <ProjetoMenuFaIcon iconClass={node.icon} className={styles.drawerDrillIcon} />
                        <span className={styles.drawerDrillLabel}>{node.label}</span>
                        <span className={styles.drawerDrillTrail}>
                            {renderBadges(node)}
                            <SidebarMenuIcon icon="angleRight" className={styles.drawerDrillChevron} />
                        </span>
                    </button>
                </li>
            );
        }

        if (node.action) {
            return (
                <li key={`${node.id}-${depth}-${index}`}>
                    <button
                        type="button"
                        className={`${styles.drawerDrillBtn} ${styles.drawerLinkButton} ${isDanger ? styles.drawerLinkDanger : ''}`}
                        onClick={() => handleLeafActivate(node)}
                    >
                        <ProjetoMenuFaIcon iconClass={node.icon} className={styles.drawerDrillIcon} />
                        <span className={styles.drawerDrillLabel}>{node.label}</span>
                        <span className={styles.drawerDrillTrail}>{renderBadges(node)}</span>
                    </button>
                </li>
            );
        }

        // `pruneEmptyMenuItems` garante que folhas sem página e sem ação não chegam aqui.
        if (!node.route || node.route === '#') {
            return null;
        }

        return (
            <li key={`${node.id}-${depth}-${index}`}>
                <Link
                    href={node.route}
                    prefetch={false}
                    className={`${styles.drawerDrillLink} ${activeLeaf ? styles.drawerDrillLinkActive : ''} ${isDanger ? styles.drawerLinkDanger : ''}`}
                    onClick={() => onClose?.()}
                    aria-current={activeLeaf ? ('page' as const) : undefined}
                >
                    <ProjetoMenuFaIcon iconClass={node.icon} className={styles.drawerDrillIcon} />
                    <span className={styles.drawerDrillLabel}>{node.label}</span>
                    <span className={styles.drawerDrillTrail}>{renderBadges(node)}</span>
                </Link>
            </li>
        );
    };

    const panelCount = drillStack.length + 1;
    const panelPx = viewportWidth;
    const usePxSlide = panelPx > 0;
    const trackWidthPx = usePxSlide ? panelPx * panelCount : null;
    const slideTxPx = usePxSlide ? -drillStack.length * panelPx : null;
    const trackPct = (drillStack.length / panelCount) * 100;

    /**
     * Rótulo do nível anterior a `level`. Tem de ser por painel: um valor único
     * derivado do topo da pilha dava o mesmo nome acessível a todos os botões
     * «Voltar», divergindo do texto visível (WCAG 2.5.3).
     */
    const parentTitleAtLevel = (level: number) =>
        level === 0 ? 'Menu do projeto' : drillStack[level - 1]?.label ?? 'Menu do projeto';

    return (
        <div className={styles.drawerContent}>
            <div className={styles.drawerSearch} role="search" aria-label="Buscar no projeto">
                <input
                    type="search"
                    placeholder="Buscar no projeto..."
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                    className={styles.drawerSearchInput}
                    aria-label="Termo de busca"
                    autoComplete="off"
                />
                {searchQuery.length > 0 ? (
                    <button
                        type="button"
                        className={styles.drawerSearchBtn}
                        aria-label="Limpar busca"
                        onClick={() => setSearchQuery('')}
                    >
                        <SidebarMenuIcon icon="times" />
                    </button>
                ) : (
                    <span className={styles.drawerSearchBtn} aria-hidden="true">
                        <ProjetoPageIcon name="search" />
                    </span>
                )}
            </div>

            {location ? (
                <p className={styles.drawerLocation} role="status">
                    {location.grupo} / {location.item}
                </p>
            ) : null}

            {isSearching ? (
                <div
                    className={styles.drawerSearchResults}
                    role="listbox"
                    aria-label="Resultados da busca no projeto"
                    data-testid="projeto-drawer-search-results"
                >
                    <div className={styles.drawerSearchResultsTitle}>Resultados</div>
                    {searchResults.length === 0 ? (
                        <p className={styles.drawerSearchEmpty}>Nenhum resultado encontrado.</p>
                    ) : (
                        <ul className={styles.drawerNavList}>
                            {searchResults.map((entry) => (
                                <li key={entry.key}>
                                    <button
                                        type="button"
                                        role="option"
                                        className={styles.drawerDrillBtn}
                                        onClick={() => handleSearchSelect(entry)}
                                    >
                                        <ProjetoMenuFaIcon
                                            iconClass={entry.node.icon}
                                            className={styles.drawerDrillIcon}
                                        />
                                        <span className={styles.drawerSearchResultText}>
                                            <span className={styles.drawerDrillLabel}>{entry.node.label}</span>
                                            <span className={styles.drawerSearchResultCrumb}>
                                                {entry.breadcrumb}
                                            </span>
                                        </span>
                                    </button>
                                </li>
                            ))}
                        </ul>
                    )}
                </div>
            ) : (
                <>
                <div
                    ref={viewportRef}
                    className={styles.drawerMenuViewport}
                    data-testid="projeto-drawer-menu-viewport"
                >
                    <div
                        className={styles.drawerMenuTrack}
                        data-testid="projeto-drawer-menu-track"
                        style={{
                            width: trackWidthPx != null ? `${trackWidthPx}px` : `${panelCount * 100}%`,
                            gridTemplateColumns: usePxSlide
                                ? `repeat(${panelCount}, ${panelPx}px)`
                                : `repeat(${panelCount}, minmax(0, 1fr))`,
                            transform:
                                slideTxPx != null
                                    ? `translate3d(${slideTxPx}px, 0, 0)`
                                    : `translateX(-${trackPct}%)`,
                        }}
                    >
                        <div className={styles.drawerMenuPanel}>
                            <nav className={styles.drawerPanelScroll} aria-label="Menu do projeto">
                                <ul className={styles.drawerNavList}>
                                    {isAplicacaoReactTipologia(categoriaCodigo) ? (
                                        <li>
                                            <Link
                                                href={getProjetoSprintAtualHref(projetoId)}
                                                prefetch={false}
                                                className={styles.drawerDrillLink}
                                                onClick={() => onClose?.()}
                                                data-testid="projeto-drawer-sprint-atual"
                                                aria-label="Abrir board da sprint atual"
                                            >
                                                <ProjetoPageIcon name="rocket" />
                                                <span className={styles.drawerDrillLabel}>Sprint atual</span>
                                            </Link>
                                        </li>
                                    ) : null}
                                    {rootNodes.map((node, index) => renderRow(node, 0, index))}
                                </ul>
                            </nav>
                        </div>

                        {drillStack.map((parent, level) => (
                            <div
                                key={`panel-${level}-${parent.id}`}
                                className={styles.drawerMenuPanel}
                            >
                                <div className={styles.drawerPanelHeader}>
                                    <button
                                        type="button"
                                        ref={
                                            level === drillStack.length - 1 ? backButtonRef : undefined
                                        }
                                        className={styles.drawerPanelBackBtn}
                                        onClick={drillOut}
                                        aria-label={`Voltar para ${parentTitleAtLevel(level)}`}
                                    >
                                        <SidebarMenuIcon icon="arrowLeft" />
                                        <span className={styles.drawerPanelBackLabel}>
                                            {parentTitleAtLevel(level)}
                                        </span>
                                    </button>
                                </div>
                                <div className={styles.drawerPanelTitle} id={`projeto-drawer-title-${level}`}>
                                    {parent.label}
                                </div>
                                <nav
                                    className={styles.drawerPanelScroll}
                                    aria-labelledby={`projeto-drawer-title-${level}`}
                                >
                                    <ul className={styles.drawerNavList}>
                                        {(parent.children ?? []).map((child, cidx) =>
                                            renderRow(child, level + 1, cidx),
                                        )}
                                    </ul>
                                </nav>
                            </div>
                        ))}
                    </div>
                </div>
                <div className={styles.drawerFooter}>
                    <Link
                        href="/projetos"
                        prefetch={false}
                        className={styles.drawerDrillLink}
                        onClick={() => onClose?.()}
                    >
                        <ProjetoPageIcon name="arrow-left" />
                        <span className={styles.drawerDrillLabel}>Voltar ao Sistema</span>
                    </Link>
                </div>
                </>
            )}
        </div>
    );
}
