'use client';

/**
 * Layout padrão de páginas de detalhe (registro único com abas, sidebar e estados de fetch).
 * Alias exportado: {@link PageDetailLayout} (nome usado na análise de produto §15.B).
 *
 * Container global (`.root`): mesma largura para cabeçalho, faixa `aboveColumns`, abas e sidebar.
 * Props úteis: `tabsVariant="pill"`, `reserveMobileActionBarSpace`, `variant="rich"`.
 * - Renderizar cabeçalho (`PageHeaderPagina`), descrições (`Descriptions`), abas ou `children`
 * - Tratar estados remotos via `fetchState`: `loading` | `error` | `not_found` | `ready`
 * - Variante `rich`: coluna principal + `sidebar` em desktop; stack em mobile (`richSidebarFirstOnNarrow`)
 *
 * Atenção:
 * - Preferir `fetchState` em vez de `loading` (deprecated)
 * - Com `tabs`, cada aba recebe `content` próprio; sem abas use `children` (+ `wrapChildrenInCard`)
 * - Usado em negócios CRM, chamados, projetos, funcionários — alterações afetam UX mobile das abas
 */

import React from 'react';
import { Tabs, Descriptions, Row, Col, Spin, Skeleton, Button, Result, Space, Affix } from 'antd';
import type { ColProps, ResultProps } from 'antd';
import { cn } from '@/lib/utils/cn';
import { useIsMobile } from '@/hooks/useIsMobile';
import PageWrapper from '../PageWrapper';
import PageHeaderPagina from '../PageHeaderPagina';
import ContentCard from '../ContentCard';
import layoutStyles from './DetailPageLayout.module.scss';

export type DetailPageVariant = 'simple' | 'rich';

export interface DetailPageTab {
    key: string;
    label: React.ReactNode;
    icon?: React.ReactNode;
    content: React.ReactNode;
}

export type DetailPageFetchState = 'loading' | 'error' | 'not_found' | 'ready';

export interface DetailPageLayoutProps {
    /**
     * `simple` — coluna única (stack em mobile).
     * `rich` — área principal + `sidebar` (metadados) em desktop; stack em `xs`.
     */
    variant?: DetailPageVariant;
    /** @deprecated Breadcrumbs removidos do produto. */
    breadcrumbItems?: Array<{ title: string; path?: string }>;
    /** @deprecated Breadcrumbs removidos do produto. */
    showBreadcrumb?: boolean;
    /** Cabeçalho da página; opcional em estados `not_found` / `error` mínimos. */
    header?: {
        title: string;
        /** Partes do título do documento (aba do browser). */
        documentTitleParts?: readonly string[];
        /** Substituto visual do título no `<h1>` (ex.: edição inline). */
        titleContent?: React.ReactNode;
        /** Mídia ou bloco à esquerda do título (ex.: foto de perfil). */
        titleLeading?: React.ReactNode;
        /** Conteúdo acima do título, à direita do `titleLeading` (ex.: código). */
        titleAboveName?: React.ReactNode;
        /** Conteúdo sob o título, à direita do `titleLeading` (ex.: estado + CPF). */
        titleBelowName?: React.ReactNode;
        /** Conteúdo ao lado do título (ex.: tags de estado). */
        titleTrailing?: React.ReactNode;
        description?: string | React.ReactNode;
        /** Estado visual junto ao bloco de descrição (ex.: `Tag`). */
        headerStatus?: React.ReactNode;
        icon?: React.ReactNode;
        actions?: React.ReactNode;
    };
    descriptions?: {
        title?: string;
        items: Array<{
            label: string;
            children: React.ReactNode;
            span?: number;
        }>;
        column?: number;
    };
    /** Só com `variant="rich"`: painel lateral (resumo, metadados). */
    sidebar?: React.ReactNode;
    /**
     * Conteúdo em largura total acima do split coluna principal / sidebar ou das abas (ex.: KPIs).
     */
    aboveColumns?: React.ReactNode;
    /**
     * Só com `variant="rich"`: em breakpoints estreitos (`xs`), empilhar a sidebar **antes**
     * da área principal (útil para resumo comercial/detalhe antes do texto longo).
     */
    richSidebarFirstOnNarrow?: boolean;
    tabs?: DetailPageTab[];
    children?: React.ReactNode;
    className?: string;
    /** Conteúdo customizado no estado `loading` (substitui Spin+Skeleton genérico). */
    loadingContent?: React.ReactNode;
    /** @deprecated Preferir `fetchState`. */
    loading?: boolean;
    /** Estado da carga remota; quando definido, tem prioridade sobre `loading`. */
    fetchState?: DetailPageFetchState;
    error?: Error | null;
    onRetry?: () => void;
    /** Título da página de erro. */
    errorTitle?: string;
    /** Subtítulo do `Result` em `fetchState === 'error'` (sobrepor `error.message`). */
    errorSubTitle?: string;
    /** Ícone/estado do `Result` em erro (ex.: `403` para acesso negado). */
    errorResultStatus?: ResultProps['status'];
    /** Ações extra junto a "Tentar novamente" (ex.: voltar à lista). */
    errorExtra?: React.ReactNode;
    /** `data-testid` no botão "Tentar novamente" (E2E). */
    errorRetryTestId?: string;
    /** Personalizar o `Result` quando `fetchState === 'not_found'`. */
    notFoundTitle?: string;
    notFoundSubTitle?: string;
    notFoundExtra?: React.ReactNode;
    /**
     * Densidade do `Result` em `not_found` / `error`: `compact` reduz padding vertical.
     */
    resultVariant?: 'default' | 'compact';
    /**
     * Quando há `children` (sem `tabs`), envolver num `ContentCard` (omissão: true).
     * Use `false` se o conteúdo já traz vários `ContentCard` próprios.
     */
    wrapChildrenInCard?: boolean;
    /**
     * Fixa o bloco do cabeçalho da página ao rolar (offset em px a partir do topo do viewport).
     * Útil em detalhes longos; omitir quando não for necessário.
     */
    affixPageHeaderOffsetTop?: number;
    /** Chave da aba ativa (modo controlado). */
    activeTabKey?: string;
    /** Callback ao mudar de aba. */
    onTabChange?: (key: string) => void;
    /** Classe CSS extra no componente `Tabs`. */
    tabsClassName?: string;
    /**
     * Estilo das abas: `default` (Ant Design) ou `pill` (scroll horizontal, tokens do tenant).
     * Com `pill`, aplica {@link layoutStyles.detailTabsPill} além de `tabsClassName`.
     */
    tabsVariant?: 'default' | 'pill';
    /**
     * Reserva espaço inferior no mobile para a barra fixa de ações (`PageHeader.actionsMobileBar`).
     */
    reserveMobileActionBarSpace?: boolean;
    /**
     * Empilha `header.actions` abaixo do título (omissão: `true`, padrão de detalhe denso).
     * Use `false` para manter o botão na mesma linha, à direita do título.
     */
    stackHeaderActionsBelow?: boolean;
    /** Conteúdo após o body principal quando `fetchState === 'ready'` (ex.: `ModuleRelatedLinksPanel` footer). */
    belowContent?: React.ReactNode;
}

function mergeDescription(
    headerStatus: React.ReactNode | undefined,
    description: string | React.ReactNode | undefined
): React.ReactNode | undefined {
    if (!headerStatus && !description) return undefined;
    return (
        <div>
            {headerStatus ? <div style={{ marginBottom: description ? 8 : 0 }}>{headerStatus}</div> : null}
            {description}
        </div>
    );
}

function renderDescriptionsBlock(
    descriptions: NonNullable<DetailPageLayoutProps['descriptions']>,
    isMobile: boolean,
) {
    return (
        <ContentCard style={{ marginBottom: 24 }}>
            {descriptions.title ? <h3 style={{ marginBottom: 16 }}>{descriptions.title}</h3> : null}
            <Descriptions
                items={descriptions.items}
                column={isMobile ? 1 : (descriptions.column ?? 2)}
                bordered
                size={isMobile ? 'small' : 'default'}
            />
        </ContentCard>
    );
}

function renderMainBody(opts: {
    descriptions?: DetailPageLayoutProps['descriptions'];
    tabs?: DetailPageTab[];
    children?: React.ReactNode;
    wrapChildrenInCard?: boolean;
    activeTabKey?: string;
    onTabChange?: (key: string) => void;
    tabsClassName?: string;
    tabsVariant?: 'default' | 'pill';
    isMobile?: boolean;
}) {
    const {
        descriptions,
        tabs,
        children,
        wrapChildrenInCard = true,
        activeTabKey,
        onTabChange,
        tabsClassName,
        tabsVariant = 'default',
        isMobile = false,
    } = opts;
    const descBlock = descriptions ? renderDescriptionsBlock(descriptions, isMobile) : null;
    const resolvedTabsClassName = cn(
        tabsVariant === 'pill' && layoutStyles.detailTabsPill,
        tabsClassName,
    );

    if (tabs && tabs.length > 0) {
        return (
            <>
                {descBlock}
                <ContentCard>
                    <Tabs
                        className={resolvedTabsClassName || undefined}
                        {...(activeTabKey != null
                            ? { activeKey: activeTabKey, onChange: onTabChange }
                            : { defaultActiveKey: tabs[0]?.key })}
                        items={tabs.map((tab) => ({
                            key: tab.key,
                            label: tab.icon ? (
                                <span
                                    style={{
                                        display: 'inline-flex',
                                        alignItems: 'center',
                                        gap: 8,
                                        minWidth: 0,
                                    }}
                                >
                                    <span style={{ display: 'inline-flex', flexShrink: 0 }}>
                                        {tab.icon}
                                    </span>
                                    <span style={{ minWidth: 0 }}>{tab.label}</span>
                                </span>
                            ) : (
                                tab.label
                            ),
                            children: tab.content,
                        }))}
                    />
                </ContentCard>
            </>
        );
    }

    if (children) {
        return (
            <>
                {descBlock}
                {wrapChildrenInCard ? <ContentCard>{children}</ContentCard> : children}
            </>
        );
    }

    return descBlock;
}

/**
 * Template de página de detalhe: cabeçalho, opcionalmente `Descriptions`, variantes simple/rico, tabs ou `children`, estados loading/erro/404.
 *
 * Para ações (editar, eliminar, "Mais"), usar {@link DetailHeaderActions} em `header.actions`.
 */
export function DetailPageLayout({
    variant = 'simple',
    header,
    descriptions,
    sidebar,
    aboveColumns,
    richSidebarFirstOnNarrow = false,
    tabs,
    children,
    loading = false,
    fetchState,
    error,
    onRetry,
    errorTitle = 'Não foi possível carregar',
    errorSubTitle,
    errorResultStatus,
    errorExtra,
    errorRetryTestId,
    notFoundTitle,
    notFoundSubTitle,
    notFoundExtra,
    resultVariant = 'default',
    wrapChildrenInCard = true,
    affixPageHeaderOffsetTop,
    activeTabKey,
    onTabChange,
    tabsClassName,
    tabsVariant = 'default',
    reserveMobileActionBarSpace = false,
    stackHeaderActionsBelow = true,
    belowContent,
    loadingContent,
    className = '',
}: DetailPageLayoutProps) {
    const isMobile = useIsMobile();
    const headerSafe = header ?? { title: '' };
    const resolvedState: DetailPageFetchState =
        fetchState ?? (loading ? 'loading' : 'ready');

    const rootClassName = cn(
        layoutStyles.root,
        reserveMobileActionBarSpace && layoutStyles.rootReserveMobileActionBar,
        className,
    );

    const renderBodyOpts = {
        descriptions,
        tabs,
        children,
        wrapChildrenInCard,
        activeTabKey,
        onTabChange,
        tabsClassName,
        tabsVariant,
        isMobile,
    };

    const descriptionMerged = mergeDescription(headerSafe.headerStatus, headerSafe.description);

    const body =
        resolvedState === 'ready' ? (
            variant === 'rich' && sidebar ? (
                <>
                    {aboveColumns ? (
                        <div className={cn(layoutStyles.aboveColumns, layoutStyles.aboveColumnsStack)}>
                            {aboveColumns}
                        </div>
                    ) : null}
                    <Row gutter={[24, 24]} className={layoutStyles.richBody}>
                        <Col
                            xs={24}
                            lg={16}
                            className={layoutStyles.colMain}
                            order={
                                (richSidebarFirstOnNarrow
                                    ? { xs: 2, sm: 2, md: 2, lg: 1 }
                                    : undefined) as unknown as ColProps['order']
                            }
                        >
                            {renderMainBody(renderBodyOpts)}
                        </Col>
                        <Col
                            xs={24}
                            lg={8}
                            className={layoutStyles.colMain}
                            order={
                                (richSidebarFirstOnNarrow
                                    ? { xs: 1, sm: 1, md: 1, lg: 2 }
                                    : undefined) as unknown as ColProps['order']
                            }
                        >
                            <div className={cn(layoutStyles.sidebarColumn, layoutStyles.sidebarStickyLite)}>
                                {sidebar}
                            </div>
                        </Col>
                    </Row>
                </>
            ) : (
                <>
                    {aboveColumns ? (
                        <div className={cn(layoutStyles.aboveColumns, layoutStyles.aboveColumnsStack)}>
                            {aboveColumns}
                        </div>
                    ) : null}
                    {renderMainBody(renderBodyOpts)}
                </>
            )
        ) : null;

    const resultCardClassName =
        resultVariant === 'compact' ? layoutStyles.resultCompact : undefined;

    const pageHeaderNode = header ? (
        <PageHeaderPagina
            title={headerSafe.title}
            documentTitleParts={headerSafe.documentTitleParts}
            titleContent={headerSafe.titleContent}
            titleLeading={headerSafe.titleLeading}
            titleAboveName={headerSafe.titleAboveName}
            titleBelowName={headerSafe.titleBelowName}
            titleTrailing={headerSafe.titleTrailing}
            actions={resolvedState === 'ready' ? headerSafe.actions : undefined}
            stackActionsBelow={stackHeaderActionsBelow}
        />
    ) : null;

    return (
        <PageWrapper className={rootClassName}>
            {pageHeaderNode ? (
                typeof affixPageHeaderOffsetTop === 'number' ? (
                    <Affix offsetTop={affixPageHeaderOffsetTop}>
                        <div style={{ width: '100%', minWidth: 0 }}>{pageHeaderNode}</div>
                    </Affix>
                ) : (
                    pageHeaderNode
                )
            ) : null}

            {resolvedState === 'ready' && (descriptionMerged || headerSafe.icon) ? (
                <div
                    style={{
                        marginBottom: 16,
                        width: '100%',
                        minWidth: 0,
                        display: 'flex',
                        gap: 8,
                        alignItems: 'flex-start',
                    }}
                >
                    {headerSafe.icon ? <span style={{ flexShrink: 0 }}>{headerSafe.icon}</span> : null}
                    {descriptionMerged ? (
                        <div style={{ minWidth: 0, flex: 1 }}>{descriptionMerged}</div>
                    ) : null}
                </div>
            ) : null}

            {resolvedState === 'loading' ? (
                loadingContent ?? (
                    <ContentCard>
                        <div style={{ textAlign: 'center', padding: '48px 24px' }}>
                            <Spin size="large" />
                        </div>
                        <Skeleton active paragraph={{ rows: 6 }} title style={{ marginTop: 24 }} />
                    </ContentCard>
                )
            ) : null}

            {resolvedState === 'not_found' ? (
                <ContentCard className={resultCardClassName}>
                    <Result
                        status="404"
                        title={notFoundTitle ?? 'Não encontrado'}
                        subTitle={
                            notFoundSubTitle ??
                            'O registro não existe ou não tem permissão para o ver.'
                        }
                        extra={
                            notFoundExtra ?? (
                                <Button type="primary" onClick={() => window.history.back()}>
                                    Voltar
                                </Button>
                            )
                        }
                    />
                </ContentCard>
            ) : null}

            {resolvedState === 'error' ? (
                <ContentCard className={resultCardClassName}>
                    <Result
                        status={errorResultStatus ?? 'error'}
                        title={errorTitle}
                        subTitle={
                            errorSubTitle ??
                            (error?.message && error.message.trim() !== ''
                                ? error.message
                                : null) ??
                            'Tente novamente dentro de instantes.'
                        }
                        extra={
                            <Space wrap>
                                {onRetry ? (
                                    <Button
                                        type="primary"
                                        onClick={onRetry}
                                        {...(errorRetryTestId ? { 'data-testid': errorRetryTestId } : {})}
                                    >
                                        Tentar novamente
                                    </Button>
                                ) : null}
                                {errorExtra}
                            </Space>
                        }
                    />
                </ContentCard>
            ) : null}

            {resolvedState === 'ready' ? body : null}
            {resolvedState === 'ready' && belowContent ? belowContent : null}
        </PageWrapper>
    );
}

export default DetailPageLayout;
