'use client';

/**
 * Abas de gestão do módulo — Visão geral | Documentação | Alterações | Páginas.
 * Usado na página de gestão e (opcionalmente) no drawer de pré-visualização.
 *
 * O formulário de changelog usa Modal (portal) para nunca ficar atrás de
 * `aria-hidden` do painel de aba inativo do Ant Design Tabs.
 */
import React, { useMemo, useState } from 'react';
import Link from 'next/link';
import {
    Alert,
    Button,
    DatePicker,
    Empty,
    Form,
    Input,
    Modal,
    Select,
    Skeleton,
    Space,
    Tabs,
    Tag,
    Timeline,
    Typography,
} from 'antd';
import dayjs from 'dayjs';
import { Plus } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import { FormTextarea } from '@/components/form';
import { message } from '@/lib/feedback/message';
import { useWaygestFormModalProps } from '@/hooks/useWaygestFormModalProps';
import { useIsMobile } from '@/hooks/useIsMobile';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import { queryKeys } from '@/lib/cache/queryKeys';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { projetosProjetoCanonical } from '@/lib/routes/projetosProjetoCanonical';
import { HISTORICO_TIPO_FILTRO_OPCOES, HISTORICO_TIPO_MANUAL_OPCOES } from './constants';
import {
    getHistoricoTipoColor,
    getHistoricoTipoLabel,
    getModuloStatusColor,
    getModuloStatusLabel,
    hasModuloStatus,
    shouldShowHistoricoTipoTag,
} from './moduloDisplay';
import type {
    ProjetoModulo,
    ProjetoModuloHistoricoFormValues,
    ProjetoModuloHistoricoListResponse,
} from './types';

const { Text, Paragraph } = Typography;

export type ModuloGestaoTabKey = 'visao' | 'doc' | 'alteracoes' | 'paginas';

export interface ModuloGestaoTabsProps {
    projetoId: string;
    moduloId: number;
    detalhe: ProjetoModulo | null | undefined;
    showLoading?: boolean;
    canEditar: boolean;
    moduloNomeById: Map<number, string>;
    /** Filhos diretos (opcional — visão geral com links). */
    filhos?: ProjetoModulo[];
    activeKey?: ModuloGestaoTabKey;
    onActiveKeyChange?: (key: ModuloGestaoTabKey) => void;
    /** Compacto no drawer; false na página de gestão. */
    compact?: boolean;
}

function DocBlock({ label, value }: { label: string; value?: string | null }) {
    if (!value?.trim()) return null;
    return (
        <div style={{ marginBottom: 16 }}>
            <Text type="secondary" style={{ display: 'block', marginBottom: 4 }}>
                {label}
            </Text>
            <Paragraph style={{ marginBottom: 0, whiteSpace: 'pre-wrap' }}>{value}</Paragraph>
        </div>
    );
}

function OverviewField({ label, children }: { label: string; children: React.ReactNode }) {
    return (
        <div style={{ marginBottom: 12 }}>
            <Text type="secondary" style={{ display: 'block', fontSize: 12 }}>
                {label}
            </Text>
            <div>{children}</div>
        </div>
    );
}

export function ModuloGestaoTabs({
    projetoId,
    moduloId,
    detalhe,
    showLoading = false,
    canEditar,
    moduloNomeById,
    filhos = [],
    activeKey,
    onActiveKeyChange,
    compact = false,
}: ModuloGestaoTabsProps) {
    const isMobile = useIsMobile();
    const [historicoTipo, setHistoricoTipo] = useState('');
    const [changelogOpen, setChangelogOpen] = useState(false);
    const [internalTab, setInternalTab] = useState<ModuloGestaoTabKey>('visao');
    const [changelogForm] = Form.useForm<ProjetoModuloHistoricoFormValues>();
    const modalLayout = useWaygestFormModalProps();
    const resolvedTab = activeKey ?? internalTab;
    const setResolvedTab = (key: ModuloGestaoTabKey) => {
        if (onActiveKeyChange) {
            onActiveKeyChange(key);
        } else {
            setInternalTab(key);
        }
    };

    const historicoParams = useMemo(
        () => ({
            page: 1,
            per_page: 50,
            ...(historicoTipo ? { tipo: historicoTipo } : {}),
        }),
        [historicoTipo],
    );

    const {
        data: historicoResponse,
        isLoading: historicoLoading,
        isError: historicoError,
        refetch: refetchHistorico,
    } = useQueryCache<ProjetoModuloHistoricoListResponse>({
        queryKey: queryKeys.projetos.moduloHistorico(projetoId, moduloId, historicoParams),
        endpoint: API_ENDPOINTS.projetos.modulos.historico.index(projetoId, moduloId),
        params: historicoParams,
        enabled: !!moduloId && !!projetoId,
        staleTime: 20 * 1000,
    });

    const historicoItems = historicoResponse?.data ?? [];

    const changelogMutation = useMutationCache({
        endpoint: API_ENDPOINTS.projetos.modulos.historico.store(projetoId, moduloId),
        method: 'POST',
        invalidateQueries: [
            queryKeys.projetos.moduloHistorico(projetoId, moduloId),
            queryKeys.projetos.modulo(projetoId, moduloId),
        ],
        onSuccess: () => {
            message.success('Alteração registrada com sucesso!');
            setChangelogOpen(false);
            changelogForm.resetFields();
            void refetchHistorico();
        },
        onError: (error: unknown) => {
            const msg =
                (error as { response?: { data?: { message?: string } } })?.response?.data
                    ?.message ?? 'Erro ao registrar alteração';
            message.error(msg);
        },
    });

    const paginas = detalhe?.paginas ?? [];
    const showPaginasTab = showLoading || paginas.length > 0;

    const closeChangelogModal = () => {
        setChangelogOpen(false);
        changelogForm.resetFields();
    };

    const handleRegistrarChangelog = async () => {
        try {
            const values = await changelogForm.validateFields();
            const body: ProjetoModuloHistoricoFormValues = {
                acao: values.acao,
                tipo: values.tipo,
                descricao: values.descricao,
                ocorrido_em: values.ocorrido_em
                    ? dayjs(values.ocorrido_em).toISOString()
                    : undefined,
            };
            changelogMutation.mutate(body);
        } catch {
            // validação
        }
    };

    /**
     * Abre Modal de changelog (sempre acessível) e garante aba Alterações ativa
     * para o operador ver o histórico após salvar.
     */
    const openChangelogForm = () => {
        setResolvedTab('alteracoes');
        changelogForm.resetFields();
        changelogForm.setFieldsValue({ tipo: 'melhoria' });
        setChangelogOpen(true);
    };

    if (showLoading && !detalhe) {
        return <Skeleton active paragraph={{ rows: compact ? 6 : 10 }} />;
    }

    if (!detalhe) {
        return (
            <Empty
                image={Empty.PRESENTED_IMAGE_SIMPLE}
                description="Módulo não encontrado."
            />
        );
    }

    const tabItems = [
        {
            key: 'visao' as const,
            label: 'Visão geral',
            children: (
                <div>
                    <OverviewField label="Status">
                        {hasModuloStatus(detalhe.status) ? (
                            <Tag color={getModuloStatusColor(detalhe.status)}>
                                {getModuloStatusLabel(detalhe.status)}
                            </Tag>
                        ) : (
                            <Text type="secondary">—</Text>
                        )}
                    </OverviewField>
                    {detalhe.codigo ? (
                        <OverviewField label="Código">
                            <Text>{detalhe.codigo}</Text>
                        </OverviewField>
                    ) : null}
                    {detalhe.pai?.nome || detalhe.modulo_pai_id ? (
                        <OverviewField label="Módulo pai">
                            {detalhe.modulo_pai_id ? (
                                <Link
                                    href={projetosProjetoCanonical.estruturaModulo(
                                        projetoId,
                                        detalhe.modulo_pai_id,
                                    )}
                                >
                                    {detalhe.pai?.nome ??
                                        moduloNomeById.get(detalhe.modulo_pai_id) ??
                                        `#${detalhe.modulo_pai_id}`}
                                </Link>
                            ) : (
                                <Text>
                                    {detalhe.pai?.nome ??
                                        (detalhe.modulo_pai_id
                                            ? moduloNomeById.get(detalhe.modulo_pai_id) ??
                                              `#${detalhe.modulo_pai_id}`
                                            : '—')}
                                </Text>
                            )}
                        </OverviewField>
                    ) : (
                        <OverviewField label="Módulo pai">
                            <Text type="secondary">Raiz</Text>
                        </OverviewField>
                    )}
                    {(detalhe.filhos_count ?? filhos.length) > 0 ? (
                        <OverviewField label="Submódulos">
                            <Text>{detalhe.filhos_count ?? filhos.length}</Text>
                        </OverviewField>
                    ) : null}
                    {filhos.length > 0 ? (
                        <OverviewField label="Submódulos vinculados">
                            <Space direction="vertical" size={4} style={{ width: '100%' }}>
                                {filhos.map((f) => (
                                    <Link
                                        key={f.id}
                                        href={projetosProjetoCanonical.estruturaModulo(
                                            projetoId,
                                            f.id,
                                        )}
                                    >
                                        {f.nome}
                                    </Link>
                                ))}
                            </Space>
                        </OverviewField>
                    ) : null}
                    {detalhe.descricao ? (
                        <OverviewField label="Descrição">
                            <Paragraph style={{ marginBottom: 0, whiteSpace: 'pre-wrap' }}>
                                {detalhe.descricao}
                            </Paragraph>
                        </OverviewField>
                    ) : null}
                    {detalhe.funcionalidades_principais ? (
                        <OverviewField label="Funcionalidades principais">
                            <Paragraph style={{ marginBottom: 0, whiteSpace: 'pre-wrap' }}>
                                {detalhe.funcionalidades_principais}
                            </Paragraph>
                        </OverviewField>
                    ) : null}
                    {detalhe.story_points != null ? (
                        <OverviewField label="Story points">
                            <Text>{detalhe.story_points}</Text>
                        </OverviewField>
                    ) : null}
                    {detalhe.tecnologias && detalhe.tecnologias.length > 0 ? (
                        <OverviewField label="Tecnologias">
                            <Space wrap size={[4, 4]}>
                                {detalhe.tecnologias.map((t) => (
                                    <Tag key={t}>{t}</Tag>
                                ))}
                            </Space>
                        </OverviewField>
                    ) : null}
                    {detalhe.dependencias && detalhe.dependencias.length > 0 ? (
                        <OverviewField label="Dependências">
                            <Space wrap size={[4, 4]}>
                                {detalhe.dependencias.map((id) => (
                                    <Tag key={id}>
                                        <Link
                                            href={projetosProjetoCanonical.estruturaModulo(
                                                projetoId,
                                                id,
                                            )}
                                        >
                                            {moduloNomeById.get(id) ?? `#${id}`}
                                        </Link>
                                    </Tag>
                                ))}
                            </Space>
                        </OverviewField>
                    ) : null}
                    {detalhe.observacoes ? (
                        <OverviewField label="Observações">
                            <Paragraph style={{ marginBottom: 0, whiteSpace: 'pre-wrap' }}>
                                {detalhe.observacoes}
                            </Paragraph>
                        </OverviewField>
                    ) : null}
                    {detalhe.criadoPor?.nome ? (
                        <OverviewField label="Criado por">
                            <Text>{detalhe.criadoPor.nome}</Text>
                        </OverviewField>
                    ) : null}
                    {detalhe.updated_at ? (
                        <OverviewField label="Atualizado em">
                            <Text>{new Date(detalhe.updated_at).toLocaleString('pt-BR')}</Text>
                        </OverviewField>
                    ) : null}
                </div>
            ),
        },
        {
            key: 'doc' as const,
            label: 'Documentação',
            children: (
                <div>
                    <DocBlock label="Objetivo" value={detalhe.documentacao_objetivo} />
                    <DocBlock label="Público-alvo" value={detalhe.documentacao_publico_alvo} />
                    <DocBlock
                        label="Regras de negócio"
                        value={detalhe.documentacao_regras_negocio}
                    />
                    <DocBlock
                        label="Dependências (texto)"
                        value={detalhe.documentacao_dependencias_texto}
                    />
                    <DocBlock label="Pendências" value={detalhe.documentacao_pendencias} />
                    <DocBlock label="Endpoints" value={detalhe.documentacao_endpoints} />
                    <DocBlock label="Componentes" value={detalhe.documentacao_componentes} />
                    <DocBlock label="Páginas (documentação)" value={detalhe.documentacao_paginas} />
                    {!detalhe.documentacao_objetivo &&
                    !detalhe.documentacao_publico_alvo &&
                    !detalhe.documentacao_regras_negocio &&
                    !detalhe.documentacao_dependencias_texto &&
                    !detalhe.documentacao_pendencias &&
                    !detalhe.documentacao_endpoints &&
                    !detalhe.documentacao_componentes &&
                    !detalhe.documentacao_paginas ? (
                        <Empty
                            image={Empty.PRESENTED_IMAGE_SIMPLE}
                            description="Nenhuma documentação cadastrada. Edite o módulo para preencher."
                        />
                    ) : null}
                </div>
            ),
        },
        {
            key: 'alteracoes' as const,
            label: 'Alterações',
            children: (
                <div>
                    <Space
                        wrap
                        style={{ width: '100%', marginBottom: 16, justifyContent: 'space-between' }}
                    >
                        <Select
                            style={{ minWidth: 180 }}
                            value={historicoTipo}
                            onChange={setHistoricoTipo}
                            options={HISTORICO_TIPO_FILTRO_OPCOES}
                            aria-label="Filtrar tipo de alteração"
                        />
                        {canEditar ? (
                            <Button
                                type={compact ? 'default' : 'primary'}
                                icon={<Plus size={ICON_SIZE_MD} aria-hidden />}
                                onClick={openChangelogForm}
                                data-testid="estrutura-modulo-registrar-alteracao"
                            >
                                Registrar alteração
                            </Button>
                        ) : null}
                    </Space>

                    {historicoError ? (
                        <Alert
                            type="error"
                            showIcon
                            message="Não foi possível carregar o histórico"
                            action={
                                <Button size="small" onClick={() => void refetchHistorico()}>
                                    Tentar novamente
                                </Button>
                            }
                            style={{ marginBottom: 16 }}
                        />
                    ) : null}

                    {historicoLoading ? (
                        <Skeleton active paragraph={{ rows: 4 }} />
                    ) : historicoItems.length === 0 ? (
                        <Empty
                            image={Empty.PRESENTED_IMAGE_SIMPLE}
                            description="Nenhuma alteração registrada ainda."
                        />
                    ) : (
                        <Timeline
                            items={historicoItems.map((item) => {
                                const tipoLabel = getHistoricoTipoLabel(item.tipo);
                                return {
                                    color: getHistoricoTipoColor(item.tipo),
                                    children: (
                                        <div>
                                            <Space wrap size={[4, 4]}>
                                                <Text strong>{item.acao}</Text>
                                                {shouldShowHistoricoTipoTag(item.tipo) ? (
                                                    <Tag color={getHistoricoTipoColor(item.tipo)}>
                                                        {tipoLabel}
                                                    </Tag>
                                                ) : null}
                                            </Space>
                                            {item.descricao ? (
                                                <Paragraph
                                                    type="secondary"
                                                    style={{
                                                        marginBottom: 4,
                                                        marginTop: 4,
                                                        whiteSpace: 'pre-wrap',
                                                    }}
                                                >
                                                    {item.descricao}
                                                </Paragraph>
                                            ) : null}
                                            {item.campo_alterado ? (
                                                <Text type="secondary" style={{ fontSize: 12 }}>
                                                    Campo: {item.campo_alterado}
                                                    {item.valor_anterior != null ||
                                                    item.valor_novo != null
                                                        ? ` (${item.valor_anterior ?? '—'} → ${item.valor_novo ?? '—'})`
                                                        : ''}
                                                </Text>
                                            ) : null}
                                            <div
                                                style={{
                                                    fontSize: 12,
                                                    color: '#8c8c8c',
                                                    marginTop: 4,
                                                }}
                                            >
                                                {[
                                                    item.usuario?.nome,
                                                    item.ocorrido_em
                                                        ? new Date(item.ocorrido_em).toLocaleString(
                                                              'pt-BR',
                                                          )
                                                        : null,
                                                ]
                                                    .filter(Boolean)
                                                    .join(' · ')}
                                            </div>
                                        </div>
                                    ),
                                };
                            })}
                        />
                    )}
                </div>
            ),
        },
        ...(showPaginasTab
            ? [
                  {
                      key: 'paginas' as const,
                      label: `Páginas${paginas.length ? ` (${paginas.length})` : ''}`,
                      children: showLoading ? (
                          <Skeleton active paragraph={{ rows: 3 }} />
                      ) : paginas.length === 0 ? (
                          <Empty
                              image={Empty.PRESENTED_IMAGE_SIMPLE}
                              description="Nenhuma página vinculada a este módulo."
                          />
                      ) : (
                          <Space direction="vertical" style={{ width: '100%' }} size={8}>
                              {paginas.map((p) => (
                                  <div
                                      key={p.id}
                                      style={{
                                          padding: '8px 12px',
                                          border: '1px solid #f0f0f0',
                                          borderRadius: 6,
                                      }}
                                  >
                                      <Text strong>{p.nome ?? p.titulo ?? `Página #${p.id}`}</Text>
                                      {p.rota ? (
                                          <div>
                                              <Text type="secondary" style={{ fontSize: 12 }}>
                                                  {p.rota}
                                              </Text>
                                          </div>
                                      ) : null}
                                  </div>
                              ))}
                          </Space>
                      ),
                  },
              ]
            : []),
    ];

    return (
        <>
            {isMobile ? (
                <div
                    style={{ marginBottom: 12 }}
                    data-testid="estrutura-modulo-gestao-section-select"
                >
                    <Select
                        value={resolvedTab}
                        onChange={(k) => setResolvedTab(k as ModuloGestaoTabKey)}
                        style={{ width: '100%' }}
                        options={tabItems.map((t) => ({
                            value: t.key,
                            label: typeof t.label === 'string' ? t.label : String(t.key),
                        }))}
                        aria-label="Seção do módulo"
                    />
                    <div style={{ marginTop: 12 }}>
                        {tabItems.find((t) => t.key === resolvedTab)?.children}
                    </div>
                </div>
            ) : (
                <Tabs
                    activeKey={resolvedTab}
                    onChange={(k) => setResolvedTab(k as ModuloGestaoTabKey)}
                    items={tabItems}
                    data-testid="estrutura-modulo-gestao-tabs"
                />
            )}

            <Modal
                {...modalLayout}
                open={changelogOpen}
                title="Nova alteração"
                onCancel={closeChangelogModal}
                destroyOnHidden
                data-testid="estrutura-modulo-changelog-modal"
                footer={
                    <Space>
                        <Button onClick={closeChangelogModal}>Cancelar</Button>
                        <Button
                            type="primary"
                            loading={changelogMutation.isPending}
                            onClick={() => void handleRegistrarChangelog()}
                        >
                            Salvar
                        </Button>
                    </Space>
                }
            >
                <Form form={changelogForm} layout="vertical">
                    <Form.Item
                        name="acao"
                        label="Título"
                        rules={[
                            {
                                required: true,
                                message: 'Informe o título da alteração',
                            },
                        ]}
                    >
                        <Input maxLength={255} placeholder="Ex.: Ajuste de fluxo de login" />
                    </Form.Item>
                    <Form.Item
                        name="tipo"
                        label="Tipo"
                        rules={[{ required: true, message: 'Selecione o tipo' }]}
                    >
                        <Select options={HISTORICO_TIPO_MANUAL_OPCOES} />
                    </Form.Item>
                    <FormTextarea
                        name="descricao"
                        label="Descrição"
                        rows={3}
                        placeholder="Detalhes opcionais"
                    />
                    <Form.Item name="ocorrido_em" label="Ocorrido em">
                        <DatePicker
                            showTime
                            style={{ width: '100%' }}
                            format="DD/MM/YYYY HH:mm"
                        />
                    </Form.Item>
                </Form>
            </Modal>
        </>
    );
}
