'use client';

import Link from 'next/link';
import { usePathname, useRouter } from 'next/navigation';
import React, { useMemo } from 'react';
import { Check, ChevronsUpDown, CornerDownRight, Plus } from 'lucide-react';
import { Dropdown } from 'antd';
import { useQueryCache } from '@/hooks/useQueryCache';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import type { Projeto } from '@/types/projeto';
import styles from './ProjetoHierarchySwitcher.module.scss';

type SuperficieItem = {
    id: number;
    nome: string;
    codigo_superficie: string | null;
    ordem: number;
    isPrograma: boolean;
};

type SubprojetosApiResponse = {
    data: Array<
        Pick<Projeto, 'id' | 'nome' | 'codigo_superficie' | 'ordem'> & {
            ordem?: number;
        }
    >;
    meta?: { total: number };
};

export type ProjetoHierarchySwitcherProps = {
    projetoId: string;
    projeto?: Projeto | null;
    /** `topHeader` — barra azul fixa; `default` — header branco da página */
    variant?: 'default' | 'topHeader';
};

function projetoSubprojetosQueryKey(programaId: string) {
    return ['projetos', 'subprojetos', programaId] as const;
}

function buildTargetPath(currentPath: string | null, fromProjetoId: string, toProjetoId: number): string {
    const fromBase = `/projetos/${fromProjetoId}`;
    const toBase = `/projetos/${toProjetoId}`;
    if (currentPath?.startsWith(fromBase)) {
        return currentPath.replace(fromBase, toBase);
    }
    return toBase;
}

/**
 * Decide apenas se o controle é montado. Continua a valer para qualquer projeto porque
 * o painel é o único caminho para criar subprojeto na maioria das tipologias — o form
 * de criação só aceita o pai por query string, e o painel do dashboard existe apenas
 * na família `geral` e nas superfícies de produto. Quem distingue «tem hierarquia» de
 * «pode ter» é `temHierarquiaReal`, dentro do componente, que ajusta rótulos e ações.
 */
export function projetoTemHierarquia(projeto: Projeto | null | undefined): boolean {
    return Boolean(projeto?.id);
}
function tituloSubprojeto(item: SuperficieItem): string {
    if (item.codigo_superficie) {
        return item.codigo_superficie.toUpperCase();
    }
    return item.nome;
}

function subtituloSubprojeto(item: SuperficieItem): string | null {
    const titulo = tituloSubprojeto(item);
    if (item.nome && item.nome !== titulo) {
        return item.nome;
    }
    return null;
}

type CascadeRowProps = {
    item: SuperficieItem;
    isActive: boolean;
    nivel: 1 | 2;
    onSelect: (id: number) => void;
};

function CascadeRow({ item, isActive, nivel, onSelect }: CascadeRowProps) {
    const isPrograma = nivel === 1;
    const titulo = isPrograma ? item.nome : tituloSubprojeto(item);
    const subtitulo = isPrograma ? null : subtituloSubprojeto(item);

    return (
        <button
            type="button"
            role="option"
            aria-selected={isActive}
            className={
                isActive
                    ? `${styles.cascadeRow} ${styles.cascadeRowActive} ${nivel === 2 ? styles.cascadeRowNivel2 : styles.cascadeRowNivel1}`
                    : `${styles.cascadeRow} ${nivel === 2 ? styles.cascadeRowNivel2 : styles.cascadeRowNivel1}`
            }
            onClick={() => {
                if (!isActive) {
                    onSelect(item.id);
                }
            }}
        >
            <span className={styles.cascadeRowCheck} aria-hidden>
                {isActive ? <Check size={14} /> : null}
            </span>
            {nivel === 2 ? (
                <CornerDownRight size={14} className={styles.cascadeRowBranch} aria-hidden />
            ) : null}
            <span className={styles.cascadeRowBody}>
                <span className={styles.cascadeRowTitulo}>{titulo}</span>
                {subtitulo ? <span className={styles.cascadeRowSubtitulo}>{subtitulo}</span> : null}
            </span>
            <span className={isPrograma ? styles.cascadeNivelBadge1 : styles.cascadeNivelBadge2}>
                Nível {nivel}
            </span>
        </button>
    );
}

/**
 * Alternância entre programa (nível 1) e subprojetos (nível 2) — ADR-0040.
 */
export function ProjetoHierarchySwitcher({
    projetoId,
    projeto,
    variant = 'default',
}: ProjetoHierarchySwitcherProps) {
    const pathname = usePathname();
    const router = useRouter();
    const isTopHeader = variant === 'topHeader';

    const programaId = projeto?.projeto_pai_id ?? projeto?.id;
    const hasHierarchy = projetoTemHierarquia(projeto);
    const canCreateSubprojeto = programaId != null;
    const createSubprojetoHref =
        programaId != null
            ? `/projetos/create?projeto_pai_id=${encodeURIComponent(String(programaId))}`
            : null;

    const { data } = useQueryCache<SubprojetosApiResponse>({
        queryKey: projetoSubprojetosQueryKey(String(programaId ?? '_')),
        endpoint: API_ENDPOINTS.projetos.subprojetos.index(programaId!),
        enabled: hasHierarchy && programaId != null,
        staleTime: 2 * 60 * 1000,
    });

    const { programa, subprojetos } = useMemo(() => {
        if (!projeto || !programaId) {
            return { programa: null as SuperficieItem | null, subprojetos: [] as SuperficieItem[] };
        }

        const programaItem: SuperficieItem = projeto.projeto_pai_id
            ? {
                  id: programaId,
                  nome: projeto.projeto_pai?.nome ?? 'Programa',
                  codigo_superficie: null,
                  ordem: -1,
                  isPrograma: true,
              }
            : {
                  id: projeto.id,
                  nome: projeto.nome,
                  codigo_superficie: null,
                  ordem: -1,
                  isPrograma: true,
              };

        const filhos = data?.data ?? [];
        const subItens: SuperficieItem[] = filhos
            .map((filho, index) => ({
                id: filho.id,
                nome: filho.nome,
                codigo_superficie: filho.codigo_superficie ?? null,
                ordem: filho.ordem ?? index,
                isPrograma: false,
            }))
            .sort((a, b) => a.ordem - b.ordem);

        return { programa: programaItem, subprojetos: subItens };
    }, [data?.data, programaId, projeto]);

    /*
     * Hierarquia efetiva: ser subprojeto, ou ter subprojetos. `subprojetos_count` vem
     * no payload do projeto e decide sem esperar a requisição; `subprojetos` cobre o
     * caso de a contagem não vir. Sem isto, o controle prometia «alternar» em projeto
     * que não tem nada para onde alternar (34 dos 35 projetos da base).
     */
    const temHierarquiaReal =
        Boolean(projeto?.projeto_pai_id) ||
        (projeto?.subprojetos_count ?? 0) > 0 ||
        subprojetos.length > 0;

    const currentId = Number(projetoId);
    const currentHomeHref = buildTargetPath(pathname, projetoId, currentId);
    const currentIsPrograma = programa?.id === currentId;
    const currentSubprojeto = subprojetos.find((item) => item.id === currentId);
    const headerSubLabel = currentSubprojeto
        ? tituloSubprojeto(currentSubprojeto)
        : (projeto?.nome ?? '');
    const headerTitle =
        programa && !currentIsPrograma
            ? `${programa.nome} / ${headerSubLabel}`
            : (programa?.nome ?? projeto?.nome ?? '');

    const navigateTo = (targetId: number) => {
        router.push(buildTargetPath(pathname, projetoId, targetId));
    };

    const dropdownPanel = (
        <div className={styles.dropdownPanel}>
            <div className={styles.dropdownHeader}>
                <span className={styles.dropdownHeaderTitulo}>
                    {temHierarquiaReal ? 'Alternar projeto' : 'Estrutura do projeto'}
                </span>
                {programa ? (
                    <span className={styles.dropdownHeaderPrograma}>{programa.nome}</span>
                ) : null}
            </div>

            <div className={styles.cascadeList} role="listbox" aria-label="Hierarquia do programa">
                {programa ? (
                    <div className={styles.cascadeGroup}>
                        <div className={styles.cascadeGroupLabel}>Programa</div>
                        <CascadeRow
                            item={programa}
                            isActive={currentId === programa.id}
                            nivel={1}
                            onSelect={navigateTo}
                        />
                    </div>
                ) : null}

                <div className={styles.cascadeGroup}>
                    <div className={styles.cascadeGroupLabel}>
                        Subprojetos
                        {subprojetos.length > 0 ? (
                            <span className={styles.cascadeGroupCount}>{subprojetos.length}</span>
                        ) : null}
                    </div>
                    {subprojetos.length > 0 ? (
                        <div className={styles.cascadeSubTree}>
                            {subprojetos.map((item) => (
                                <CascadeRow
                                    key={item.id}
                                    item={item}
                                    isActive={currentId === item.id}
                                    nivel={2}
                                    onSelect={navigateTo}
                                />
                            ))}
                        </div>
                    ) : (
                        <p className={styles.cascadeEmpty}>
                            Este projeto ainda não tem subprojetos.
                        </p>
                    )}
                </div>
            </div>

            {canCreateSubprojeto && createSubprojetoHref ? (
                <div className={styles.dropdownActions}>
                    <Link href={createSubprojetoHref} className={styles.dropdownActionLink}>
                        <Plus size={14} aria-hidden />
                        {temHierarquiaReal ? 'Novo subprojeto' : 'Criar o primeiro subprojeto'}
                    </Link>
                </div>
            ) : null}

            {temHierarquiaReal ? (
                <div className={styles.dropdownFooter}>
                    <span>
                        1 programa · {subprojetos.length}{' '}
                        {subprojetos.length === 1 ? 'subprojeto' : 'subprojetos'}
                    </span>
                </div>
            ) : null}
        </div>
    );

    if (!hasHierarchy || !projeto || !programaId || !programa) {
        return null;
    }

    const rootClass = isTopHeader ? styles.rootTopHeader : styles.rootDefault;
    const titleClass = isTopHeader ? styles.selectorLabelTopHeader : styles.selectorLabelDefault;
    const compoundClass = isTopHeader ? styles.selectorCompoundTopHeader : styles.selectorCompoundDefault;
    const triggerClass = isTopHeader ? styles.selectorTriggerTopHeader : styles.selectorTriggerDefault;

    const titleContent =
        currentIsPrograma || !programa ? (
            <span className={styles.currentTitleText}>{programa?.nome ?? projeto?.nome}</span>
        ) : (
            <span className={styles.currentTitleStack}>
                <span className={styles.currentTitlePrograma}>{programa.nome}</span>
                <span className={styles.currentTitleSep} aria-hidden>
                    /
                </span>
                <span className={styles.currentTitleSub}>{headerSubLabel}</span>
            </span>
        );

    return (
        <div
            className={rootClass}
            data-testid="projeto-hierarchy-switcher"
            aria-label="Hierarquia do programa"
        >
            <div className={compoundClass}>
                <Link href={currentHomeHref} className={titleClass} title={headerTitle}>
                    {titleContent}
                </Link>

                <span className={styles.selectorDivider} aria-hidden />

                <Dropdown
                    trigger={['click']}
                    placement="bottomLeft"
                    overlayClassName={styles.dropdownOverlay}
                    popupRender={() => dropdownPanel}
                >
                    <button
                        type="button"
                        className={triggerClass}
                        aria-label={
                            temHierarquiaReal
                                ? 'Alternar entre programa e subprojetos'
                                : 'Estrutura do projeto'
                        }
                        aria-haspopup={temHierarquiaReal ? 'listbox' : 'dialog'}
                    >
                        <ChevronsUpDown size={16} aria-hidden />
                    </button>
                </Dropdown>
            </div>
        </div>
    );
}
