'use client';

/**
 * Páginas tipológicas do projeto (`/projetos/[id]/estrutura/paginas`).
 * Listagem paginada server-side — contrato `ProjetoPaginaResource` (TASK-PWP-019).
 */
import { FileText, Link, Menu as MenuIcon, Plus } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import React, { useCallback, useMemo, useState } from 'react';
import { useRouter } from 'next/navigation';
import { keepPreviousData } from '@tanstack/react-query';
import { Button, Space, Tag, Modal, Form, Input, Select, Descriptions, Tooltip } from 'antd';
import { message } from '@/lib/feedback/message';
import { LazyExportButton } from '@/components/lazy';
import { LazyDataTable } from '@/components/lazy';
import type { ColumnsType, TableProps } from 'antd/es/table';
import { PermissionGuard } from '@/components/permissions';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import { useWaygestFormModalProps } from '@/hooks/useWaygestFormModalProps';
import { usePaginatedResponseFallback } from '@/hooks/usePaginatedResponseFallback';
import { queryKeys } from '@/lib/cache/queryKeys';
import apiClient from '@/lib/api/client';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { formatDate } from '@/lib/utils/export';
import { detailPageQueryErrorSubTitle } from '@/lib/utils/detailPageQueryErrorSubTitle';
import { FormTextarea } from '@/components/form';
import ProjetoLayout from '@/components/layouts/ProjetoLayout';
import { OperativeRouteHint } from '@/components/layouts/OperativeRouteHint/OperativeRouteHint';
import {
    ListPageCreateFloatButton,
    ListagemListaError,
} from '@/components/listings';
import btnHeaderStyles from '@/components/ui/buttons/ButtonHeaderIcon/ButtonHeaderIcon.module.scss';
import { projetosProjetoCanonical } from '@/lib/routes/projetosProjetoCanonical';
import { EmptyState } from '@/components/empty';
import { ModalOpcoesPagina } from './ModalOpcoesPagina';
import type { PaginaProjeto, PaginaProjetoType, PaginasProjetoListResponse } from './types';
import {
    METODO_HTTP_OPCOES,
    PAGINAS_LIST_DEFAULT_PER_PAGE,
    STATUS_OPCOES,
    TIPO_OPCOES,
    VISIBILIDADE_OPCOES,
} from './constants';
import {
    getEstruturaPaginaStatusColor,
    getEstruturaPaginaStatusLabel,
    getEstruturaPaginaTipoColor,
    getEstruturaPaginaVisibilidadeColor,
} from './estruturaPaginasDisplay';

const EMPTY_ROWS: PaginaProjeto[] = [];

export interface ProjetoEstruturaPaginasScreenProps {
    projetoId: string;
}

export function ProjetoEstruturaPaginasScreen({ projetoId: id }: ProjetoEstruturaPaginasScreenProps) {
    const router = useRouter();
    const [page, setPage] = useState(1);
    const [perPage, setPerPage] = useState(PAGINAS_LIST_DEFAULT_PER_PAGE);
    const [modalVisible, setModalVisible] = useState(false);
    const [viewModalVisible, setViewModalVisible] = useState(false);
    const [selectedPagina, setSelectedPagina] = useState<PaginaProjeto | null>(null);
    const [editingPagina, setEditingPagina] = useState<PaginaProjeto | null>(null);
    const [form] = Form.useForm();
    const modalLayout = useWaygestFormModalProps();
    const [opcoesItem, setOpcoesItem] = useState<PaginaProjeto | null>(null);

    const listParams = useMemo(
        () => ({ page, per_page: perPage }),
        [page, perPage],
    );

    const {
        data: paginasData,
        isLoading,
        isError,
        error: paginasQueryError,
        refetch,
        isFetching,
    } = useQueryCache<PaginasProjetoListResponse>({
        queryKey: queryKeys.projetos.paginasList(id, listParams),
        endpoint: API_ENDPOINTS.projetos.paginas.index(id),
        params: listParams,
        enabled: !!id,
        staleTime: 1 * 60 * 1000,
        gcTime: 5 * 60 * 1000,
        placeholderData: keepPreviousData,
    });

    const paginatedData = usePaginatedResponseFallback(paginasData, perPage, EMPTY_ROWS);
    const paginas = useMemo(
        () => (Array.isArray(paginatedData.data) ? paginatedData.data.filter(Boolean) : []),
        [paginatedData.data],
    );

    const handleTableChange = useCallback<NonNullable<TableProps<PaginaProjeto>['onChange']>>(
        (pagination, _filters, _sorter, extra) => {
            if (extra.action === 'paginate') {
                if (pagination.current != null) setPage(pagination.current);
                if (pagination.pageSize != null) setPerPage(pagination.pageSize);
            }
        },
        [],
    );

    const saveMutation = useMutationCache({
        endpoint: editingPagina
            ? API_ENDPOINTS.projetos.paginas.update(id, editingPagina.id)
            : API_ENDPOINTS.projetos.paginas.store(id),
        method: editingPagina ? 'PUT' : 'POST',
        invalidateQueries: [queryKeys.projetos.paginas(id)],
        onSuccess: () => {
            message.success(
                editingPagina ? 'Página atualizada com sucesso!' : 'Página criada com sucesso!',
            );
            setModalVisible(false);
            form.resetFields();
            refetch();
        },
        onError: (mutationError: unknown) => {
            const errorMessage =
                (mutationError as { response?: { data?: { message?: string } } })?.response?.data
                    ?.message || 'Erro ao salvar página';
            message.error(errorMessage);
        },
    });

    const handleCreate = () => {
        setEditingPagina(null);
        form.resetFields();
        setModalVisible(true);
    };

    const handleEdit = (pagina: PaginaProjeto) => {
        setEditingPagina(pagina);
        form.setFieldsValue(pagina);
        setModalVisible(true);
    };

    const handleDelete = async (paginaId: number) => {
        try {
            const endpoint = API_ENDPOINTS.projetos.paginas.destroy(id, paginaId);
            await apiClient.delete(endpoint);
            message.success('Página excluída com sucesso!');
            refetch();
        } catch (deleteError: unknown) {
            const errorMessage =
                (deleteError as { response?: { data?: { message?: string } } })?.response?.data
                    ?.message || 'Erro ao excluir página';
            message.error(errorMessage);
        }
    };

    const handleSubmit = (values: Record<string, unknown>) => {
        saveMutation.mutate(values);
    };

    const columns: ColumnsType<PaginaProjeto> = useMemo(
        () => [
            {
                title: 'Título',
                dataIndex: 'titulo',
                key: 'titulo',
                render: (text: string, record: PaginaProjeto) => (
                    <Space>
                        <FileText size={ICON_SIZE_MD} aria-hidden />
                        <span style={{ fontWeight: 600, color: '#2c3e50' }}>{text}</span>
                        <Tag color={getEstruturaPaginaTipoColor(record.tipo)}>{record.tipo}</Tag>
                    </Space>
                ),
            },
            {
                title: 'Slug',
                dataIndex: 'slug',
                key: 'slug',
                width: 180,
                ellipsis: true,
                render: (slug: string) => (
                    <Space>
                        <Link size={ICON_SIZE_MD} aria-hidden />
                        <span style={{ color: '#666', fontFamily: 'monospace' }}>{slug}</span>
                    </Space>
                ),
            },
            {
                title: 'Método',
                dataIndex: 'metodo_http',
                key: 'metodo_http',
                width: 88,
                render: (metodo: string) => (
                    <Tag>{metodo || 'GET'}</Tag>
                ),
            },
            {
                title: 'Status',
                dataIndex: 'status',
                key: 'status',
                width: 130,
                render: (status: string) => (
                    <Tag color={getEstruturaPaginaStatusColor(status)}>
                        {getEstruturaPaginaStatusLabel(status)}
                    </Tag>
                ),
            },
            {
                title: 'Visibilidade',
                dataIndex: 'visibilidade',
                key: 'visibilidade',
                width: 120,
                render: (visibilidade: string) => (
                    <Tag color={getEstruturaPaginaVisibilidadeColor(visibilidade)}>
                        {visibilidade.charAt(0).toUpperCase() + visibilidade.slice(1)}
                    </Tag>
                ),
            },
            {
                title: 'Autor',
                dataIndex: ['autor', 'nome'],
                key: 'autor',
                width: 140,
                render: (_: unknown, record: PaginaProjeto) => record.autor?.nome ?? '—',
            },
            {
                title: 'Atualizado em',
                dataIndex: 'updated_at',
                key: 'updated_at',
                width: 130,
                render: (date: string) => (date ? formatDate(date, true) : '—'),
            },
            {
                title: '',
                key: 'menu',
                width: 56,
                align: 'center',
                fixed: 'right',
                onCell: () => ({ onClick: (e: React.MouseEvent) => e.stopPropagation() }),
                render: (_: unknown, record: PaginaProjeto) => (
                    <Button
                        type="text"
                        size="small"
                        icon={<MenuIcon size={ICON_SIZE_MD} aria-hidden />}
                        onClick={() => setOpcoesItem(record)}
                        aria-label="Opções"
                    />
                ),
            },
        ],
        [],
    );

    const showEmptyState =
        !isLoading && !isError && (paginatedData.meta.total ?? 0) === 0;
    const showTable = !isError && (paginatedData.meta.total ?? 0) > 0;

    if (!id) return null;

    return (
        <ProjetoLayout
            projetoId={id}
            pageTitle="Páginas do Projeto"
            showPageTitleIcon={false}
            titleSection="Páginas"
            breadcrumbItems={[
                { title: 'PROJETO' },
                { title: 'Projeto', path: `/projetos/${id}` },
                { title: 'Estrutura' },
                { title: 'Páginas' },
            ]}
            headerAction={
                <Space wrap size={8} align="center">
                    <Tooltip title="Exportar páginas visíveis nesta página (Excel, PDF, CSV ou JSON)">
                        <span style={{ display: 'inline-block' }}>
                            <LazyExportButton
                                data={paginas as unknown as Record<string, unknown>[]}
                                columns={[
                                    { key: 'titulo', label: 'Título' },
                                    { key: 'slug', label: 'Slug' },
                                    { key: 'metodo_http', label: 'Método HTTP' },
                                    { key: 'status', label: 'Status' },
                                    { key: 'tipo', label: 'Tipo' },
                                    { key: 'visibilidade', label: 'Visibilidade' },
                                ]}
                                filename={`paginas_projeto_${id}`}
                                iconOnly
                                title="Exportar páginas do projeto"
                                size="large"
                                exportMenuMode="modal"
                                className={btnHeaderStyles.btnHeaderIcon}
                            />
                        </span>
                    </Tooltip>
                </Space>
            }
        >
            <OperativeRouteHint
                message="Cobertura e documentação de páginas"
                description="Acompanhe rotas, método HTTP e status operacional (ativa, deprecada, em manutenção). Priorize páginas sem dono ou desatualizadas no refinamento com a equipe."
            >
                <Space wrap>
                    <Button size="small" type="link" onClick={() => router.push(projetosProjetoCanonical.estruturaModulos(id))}>
                        Módulos do sistema
                    </Button>
                </Space>
            </OperativeRouteHint>

            {isError && !paginasData ? (
                <ListagemListaError
                    message="Não foi possível carregar as páginas"
                    description={detailPageQueryErrorSubTitle(paginasQueryError)}
                    onRetry={() => void refetch()}
                    data-testid="projeto-estrutura-paginas-lista-retry"
                />
            ) : showEmptyState ? (
                <EmptyState
                    title="Nenhuma página encontrada"
                    description="Cadastre a primeira página de documentação do projeto — título, rota, método HTTP e conteúdo."
                    icon={<FileText size={ICON_SIZE_MD} aria-hidden />}
                    action={
                        <PermissionGuard permission="projetos.paginas.cadastrar">
                            <Button
                                type="primary"
                                icon={<Plus size={ICON_SIZE_MD} aria-hidden />}
                                onClick={handleCreate}
                            >
                                Criar primeira página
                            </Button>
                        </PermissionGuard>
                    }
                />
            ) : showTable ? (
                <LazyDataTable
                    rowKey="id"
                    columns={columns}
                    data={paginas}
                    loading={isLoading}
                    fetching={isFetching}
                    onRefresh={refetch}
                    onChange={handleTableChange}
                    scroll={{ x: 960 }}
                    pagination={{
                        current: paginatedData.meta.current_page,
                        pageSize: paginatedData.meta.per_page,
                        total: paginatedData.meta.total,
                        showSizeChanger: true,
                        pageSizeOptions: ['15', '25', '50', '100'],
                        showTotal: (total) => `${total} página(s)`,
                    }}
                    onRow={(record: unknown) => ({
                        onClick: () => setOpcoesItem(record as PaginaProjeto),
                        style: { cursor: 'pointer' },
                    })}
                    data-testid="projeto-estrutura-paginas-table"
                />
            ) : null}

            <ModalOpcoesPagina
                open={opcoesItem !== null}
                onClose={() => setOpcoesItem(null)}
                item={opcoesItem}
                onVerDetalhes={(item: PaginaProjetoType) => {
                    setOpcoesItem(null);
                    setSelectedPagina(item as PaginaProjeto);
                    setViewModalVisible(true);
                }}
                onEditar={(item: PaginaProjetoType) => {
                    setOpcoesItem(null);
                    handleEdit(item as PaginaProjeto);
                }}
                onExcluir={(item: PaginaProjetoType) => {
                    setOpcoesItem(null);
                    handleDelete(item.id);
                }}
            />

            <Modal
                title={editingPagina ? 'Editar Página' : 'Nova Página'}
                open={modalVisible}
                onCancel={() => {
                    setModalVisible(false);
                    form.resetFields();
                }}
                onOk={() => form.submit()}
                confirmLoading={saveMutation.isPending}
                width={modalLayout.width ?? 800}
                centered={modalLayout.centered ?? true}
                className={modalLayout.className}
                styles={modalLayout.styles ?? {}}
                destroyOnHidden
                keyboard
                focusTriggerAfterClose
                data-testid="projeto-estrutura-paginas-form-modal"
            >
                <Form
                    form={form}
                    onFinish={handleSubmit}
                    layout="vertical"
                    initialValues={{
                        tipo: 'documentacao',
                        visibilidade: 'publica',
                        metodo_http: 'GET',
                        status: 'ativa',
                    }}
                >
                    <Form.Item
                        name="titulo"
                        label="Título"
                        rules={[{ required: true, message: 'Título é obrigatório' }]}
                    >
                        <Input placeholder="Ex: Documentação Inicial" />
                    </Form.Item>

                    <Form.Item
                        name="slug"
                        label="Slug (URL)"
                        rules={[{ required: true, message: 'Slug é obrigatório' }]}
                    >
                        <Input placeholder="/documentacao-inicial" />
                    </Form.Item>

                    <Form.Item name="metodo_http" label="Método HTTP" rules={[{ required: true }]}>
                        <Select options={METODO_HTTP_OPCOES} placeholder="Selecione o método" />
                    </Form.Item>

                    <Form.Item name="status" label="Status" rules={[{ required: true }]}>
                        <Select options={STATUS_OPCOES} placeholder="Selecione o status" />
                    </Form.Item>

                    <Form.Item name="tipo" label="Tipo" rules={[{ required: true }]}>
                        <Select options={TIPO_OPCOES} placeholder="Selecione o tipo" />
                    </Form.Item>

                    <Form.Item name="visibilidade" label="Visibilidade" rules={[{ required: true }]}>
                        <Select options={VISIBILIDADE_OPCOES} placeholder="Selecione a visibilidade" />
                    </Form.Item>

                    <FormTextarea
                        name="conteudo"
                        label="Conteúdo"
                        rows={10}
                        placeholder="Digite o conteúdo da página..."
                        required
                    />
                </Form>
            </Modal>

            <Modal
                title={selectedPagina?.titulo}
                open={viewModalVisible}
                onCancel={() => setViewModalVisible(false)}
                footer={[
                    <Button key="close" onClick={() => setViewModalVisible(false)}>
                        Fechar
                    </Button>,
                ]}
                width={modalLayout.width ?? 900}
                centered={modalLayout.centered ?? true}
                className={modalLayout.className}
                styles={modalLayout.styles ?? {}}
                destroyOnHidden
                keyboard
                focusTriggerAfterClose
                data-testid="projeto-estrutura-paginas-detalhes-modal"
            >
                {selectedPagina && (
                    <div>
                        <Descriptions bordered column={2} style={{ marginBottom: 24 }}>
                            <Descriptions.Item label="Slug">
                                <code>{selectedPagina.slug}</code>
                            </Descriptions.Item>

                            <Descriptions.Item label="Método HTTP">
                                <Tag>{selectedPagina.metodo_http ?? 'GET'}</Tag>
                            </Descriptions.Item>

                            <Descriptions.Item label="Status">
                                <Tag color={getEstruturaPaginaStatusColor(selectedPagina.status)}>
                                    {getEstruturaPaginaStatusLabel(selectedPagina.status)}
                                </Tag>
                            </Descriptions.Item>

                            <Descriptions.Item label="Tipo">
                                <Tag color={getEstruturaPaginaTipoColor(selectedPagina.tipo)}>
                                    {selectedPagina.tipo}
                                </Tag>
                            </Descriptions.Item>

                            <Descriptions.Item label="Visibilidade">
                                <Tag
                                    color={getEstruturaPaginaVisibilidadeColor(
                                        selectedPagina.visibilidade,
                                    )}
                                >
                                    {selectedPagina.visibilidade.charAt(0).toUpperCase() +
                                        selectedPagina.visibilidade.slice(1)}
                                </Tag>
                            </Descriptions.Item>

                            <Descriptions.Item label="Autor">
                                {selectedPagina.autor?.nome ?? '—'}
                            </Descriptions.Item>

                            <Descriptions.Item label="Versão">
                                <Tag>v{selectedPagina.versao ?? 1}</Tag>
                            </Descriptions.Item>

                            <Descriptions.Item label="Criado em" span={2}>
                                {selectedPagina.created_at
                                    ? formatDate(selectedPagina.created_at, true)
                                    : '—'}
                            </Descriptions.Item>
                        </Descriptions>

                        <div
                            style={{
                                padding: 16,
                                background: '#f5f5f5',
                                borderRadius: 4,
                                whiteSpace: 'pre-wrap',
                                maxHeight: 500,
                                overflow: 'auto',
                            }}
                        >
                            {selectedPagina.conteudo}
                        </div>
                    </div>
                )}
            </Modal>

            <PermissionGuard permission="projetos.paginas.cadastrar">
                <ListPageCreateFloatButton
                    data-testid="projeto-estrutura-paginas-fab-nova"
                    tooltip={{ title: 'Nova página de documentação' }}
                    onClick={handleCreate}
                />
            </PermissionGuard>
        </ProjetoLayout>
    );
}
