'use client';

/**
 * Modal — relatório de bugs / prompt de correção em lote (módulo único suporte/logs).
 * Usado na listagem global (com projeto_id) e na vista embutida do projeto.
 * @see docs/modulos/projetos/planos/plano-menu-status-logs-prompt-correcao.md
 */
import React, { useCallback, useEffect, useState } from 'react';
import { queryKeys } from '@/lib/cache/queryKeys';
import { Alert, Button, Modal, Select, Space, Spin, Typography } from 'antd';
import { message } from '@/lib/feedback/message';
import { confirmDialog } from '@/lib/feedback/confirmDialog';
import apiClient from '@/lib/api/client';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { useQueryClient } from '@tanstack/react-query';
import {
    mergeWaygestFormModalBodyStyles,
    useWaygestFormModalProps,
} from '@/hooks/useWaygestFormModalProps';

export type ProjetoLogBugReportMeta = {
    projeto: { id: number; nome: string; tipo?: string | null };
    cliente: { id: number; nome: string } | null;
    por_nivel: { critical: number; error: number; warning: number };
    incluidos: number;
    defects_incluidos?: number;
    ocorrencias_incluidas?: number;
    prompt_version?: string;
    limit?: number;
    ambientes?: string[];
    /** Níveis incluídos no prompt (critical/error/warning). */
    niveis_prompt?: string[];
    /** Total não resolvidos na listagem (qualquer nível). */
    pendentes_listagem?: number;
    /** Pendentes fora dos níveis do prompt (ex.: notice/info). */
    pendentes_outros_niveis?: number;
};

export type ProjetoLogBugReportResponse = {
    prompt: string;
    truncado: boolean;
    total_pendentes: number;
    log_ids: number[];
    meta: ProjetoLogBugReportMeta;
};

export type ProjetoLogBugReportMarcarResponse = {
    message?: string;
    prompt?: number;
    duplicados?: number;
    total?: number;
    ids?: number[];
};

/** Opções de lote no prompt (alinhado ao teto da API = 2000). */
export const RELATORIO_BUGS_LIMIT_OPTIONS = [100, 250, 500, 1000, 2000] as const;
export const RELATORIO_BUGS_DEFAULT_LIMIT = 100;

export interface ModalRelatorioBugsProjetoProps {
    open: boolean;
    onClose: () => void;
    projetoId: string;
    /** Após marcar resolvidos — refresh da listagem. */
    onResolvidos?: () => void;
}

export function ModalRelatorioBugsProjeto({
    open,
    onClose,
    projetoId,
    onResolvidos,
}: ModalRelatorioBugsProjetoProps) {
    const queryClient = useQueryClient();
    const modalLayout = useWaygestFormModalProps();
    const modalStyles = mergeWaygestFormModalBodyStyles(modalLayout);

    const [loading, setLoading] = useState(false);
    const [busy, setBusy] = useState(false);
    const [data, setData] = useState<ProjetoLogBugReportResponse | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [limit, setLimit] = useState<number>(RELATORIO_BUGS_DEFAULT_LIMIT);
    const [lastResolvedIds, setLastResolvedIds] = useState<number[] | null>(null);

    const load = useCallback(async (limitAtual: number) => {
        setLoading(true);
        setError(null);
        setLastResolvedIds(null);
        try {
            const res = await apiClient.get<ProjetoLogBugReportResponse>(
                API_ENDPOINTS.projetos.logs.relatorioBugs(projetoId),
                { params: { limit: limitAtual } },
            );
            setData(res.data);
        } catch (e) {
            setData(null);
            setError(getLaravelApiErrorMessage(e) || 'Não foi possível gerar o relatório.');
        } finally {
            setLoading(false);
        }
    }, [projetoId]);

    useEffect(() => {
        if (open && projetoId) {
            void load(limit);
        }
        if (!open) {
            setData(null);
            setError(null);
            setLastResolvedIds(null);
            setLimit(RELATORIO_BUGS_DEFAULT_LIMIT);
        }
        // Só dispara ao abrir / mudar projeto; troca de limit é via onChange do Select.
        // eslint-disable-next-line react-hooks/exhaustive-deps -- limit tratado no Select
    }, [open, projetoId, load]);

    const handleLimitChange = (next: number) => {
        setLimit(next);
        if (open && projetoId) {
            void load(next);
        }
    };

    const handleCopiar = async () => {
        if (!data?.prompt) return;
        try {
            await navigator.clipboard.writeText(data.prompt);
        } catch {
            message.error('Não foi possível copiar. Selecione o texto manualmente.');
        }
    };

    const handleMarcarResolvidos = () => {
        if (!data?.log_ids?.length) return;
        confirmDialog({
            title: 'Marcar bugs do prompt como resolvidos?',
            content:
                'Também serão resolvidos logs pendentes equivalentes (mesmo nível + mensagem normalizada) neste projeto, mesmo fora deste prompt.',
            okText: 'Marcar resolvidos',
            cancelText: 'Cancelar',
            onOk: async () => {
                setBusy(true);
                try {
                    const res = await apiClient.post<ProjetoLogBugReportMarcarResponse>(
                        API_ENDPOINTS.projetos.logs.marcarResolvidosRelatorio(projetoId),
                        {
                            log_ids: data.log_ids,
                            incluir_equivalentes: true,
                        },
                    );
                    const ids = res.data.ids ?? data.log_ids;
                    setLastResolvedIds(ids);
                    message.success(
                        res.data.message ||
                            `${res.data.total ?? ids.length} log(s) marcado(s) como resolvido(s).`,
                    );
                    void queryClient.invalidateQueries({ queryKey: queryKeys.projetos.logs.all });
                    onResolvidos?.();
                    await load(limit);
                } catch (e) {
                    message.error(
                        getLaravelApiErrorMessage(e) || 'Não foi possível marcar como resolvidos.',
                    );
                    throw e;
                } finally {
                    setBusy(false);
                }
            },
        });
    };

    const handleVoltarPendentes = async () => {
        if (!lastResolvedIds?.length) return;
        setBusy(true);
        try {
            await apiClient.post(
                API_ENDPOINTS.projetos.logs.voltarPendentesRelatorio(projetoId),
                { log_ids: lastResolvedIds },
            );
            message.success('Logs reabertos como pendentes.');
            setLastResolvedIds(null);
            void queryClient.invalidateQueries({ queryKey: queryKeys.projetos.logs.all });
            onResolvidos?.();
            await load(limit);
        } catch (e) {
            message.error(getLaravelApiErrorMessage(e) || 'Não foi possível reabrir os logs.');
        } finally {
            setBusy(false);
        }
    };

    const vazios = !loading && !error && data && data.total_pendentes === 0;
    const meta = data?.meta;

    return (
        <Modal
            title="Prompt de correção (bugs do projeto)"
            open={open}
            onCancel={onClose}
            width={840}
            destroyOnHidden
            styles={modalStyles}
            footer={
                <Space wrap>
                    <Button onClick={onClose}>Fechar</Button>
                    {lastResolvedIds && lastResolvedIds.length > 0 && (
                        <Button onClick={() => void handleVoltarPendentes()} loading={busy}>
                            Voltar para pendentes
                        </Button>
                    )}
                    {!vazios && data && data.log_ids.length > 0 && (
                        <Button danger onClick={handleMarcarResolvidos} loading={busy}>
                            Marcar bugs do prompt como resolvidos
                        </Button>
                    )}
                    {!vazios && data?.prompt && (
                        <Button type="primary" onClick={() => void handleCopiar()}>
                            Copiar prompt
                        </Button>
                    )}
                </Space>
            }
            data-testid="projeto-modal-relatorio-bugs"
        >
            {loading && (
                <div style={{ textAlign: 'center', padding: 48 }}>
                    <Spin size="large" />
                </div>
            )}

            {error && (
                <Alert
                    type="error"
                    showIcon
                    message={error}
                    action={<Button onClick={() => void load(limit)}>Tentar de novo</Button>}
                />
            )}

            {vazios && (
                <Alert
                    type="info"
                    showIcon
                    message="Nenhum bug elegível para o prompt"
                    description={
                        (meta?.pendentes_outros_niveis ?? 0) > 0 ? (
                            <>
                                O prompt de correção só inclui logs{' '}
                                <strong>critical, error e warning</strong> não resolvidos.
                                Há{' '}
                                <strong>{meta?.pendentes_outros_niveis}</strong> log(s) pendente(s) em
                                outros níveis (ex.: notice, info, debug) — eles aparecem na aba
                                Pendentes da listagem, mas não entram neste relatório. Trate-os na
                                tabela ou filtre por nível.
                            </>
                        ) : (
                            <>
                                Não há logs critical/error/warning não resolvidos. Se ainda não há
                                eventos, configure o{' '}
                                <a href={`/projetos/${projetoId}/conectar`}>
                                    logs-package em Conectar projeto
                                </a>
                                .
                            </>
                        )
                    }
                />
            )}

            {!loading && !error && data && data.total_pendentes > 0 && (
                <>
                    <Space
                        wrap
                        align="center"
                        style={{ width: '100%', justifyContent: 'space-between', marginBottom: 12 }}
                    >
                        <Typography.Paragraph type="secondary" style={{ marginBottom: 0 }}>
                            {meta?.cliente ? `Cliente: ${meta.cliente.nome} · ` : null}
                            Projeto: {meta?.projeto.nome ?? projetoId}
                            {meta?.projeto.tipo ? ` (${meta.projeto.tipo})` : ''}
                            {' · '}
                            Pendentes: {data.total_pendentes}
                            {' · '}
                            Neste prompt:{' '}
                            {meta?.defects_incluidos != null
                                ? `${meta.defects_incluidos} defect(s) · ${meta.ocorrencias_incluidas ?? meta.incluidos ?? data.log_ids.length} ocorrência(s)`
                                : (meta?.incluidos ?? data.log_ids.length)}
                            {data.truncado ? ' (truncado — marque resolvidos e gere novo relatório)' : ''}
                            {meta?.prompt_version ? ` · ${meta.prompt_version}` : ''}
                            {meta?.por_nivel
                                ? ` · critical=${meta.por_nivel.critical} · error=${meta.por_nivel.error} · warning=${meta.por_nivel.warning}`
                                : null}
                        </Typography.Paragraph>
                        <Space size={8} align="center">
                            <Typography.Text type="secondary">Logs por vez</Typography.Text>
                            <Select<number>
                                value={limit}
                                onChange={handleLimitChange}
                                style={{ width: 110 }}
                                options={RELATORIO_BUGS_LIMIT_OPTIONS.map((n) => ({
                                    value: n,
                                    label: String(n),
                                }))}
                                aria-label="Quantidade de logs no prompt"
                                data-testid="projeto-relatorio-bugs-limit"
                            />
                        </Space>
                    </Space>

                    <Alert
                        type="warning"
                        showIcon
                        style={{ marginBottom: 12 }}
                        message="Privacidade (LGPD)"
                        description="Revise o prompt antes de colar em um LLM. Não deve conter PII desnecessária; o conteúdo já vem parcialmente redigido."
                    />

                    <Typography.Paragraph>
                        Copie o texto abaixo e cole num chat do Cursor. O prompt pede Defects
                        pré-agrupados, premissas de qualidade (nota 10), ciclo completo de correção e
                        validação ao vivo em local/staging/homolog — nunca produção. Marque
                        resolvidos no ERP só após aceitar a entrega.
                    </Typography.Paragraph>

                    <textarea
                        readOnly
                        value={data.prompt}
                        rows={18}
                        style={{
                            width: '100%',
                            fontFamily:
                                'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
                            fontSize: 12,
                            lineHeight: 1.45,
                            padding: 12,
                            borderRadius: 8,
                            border: '1px solid var(--border, #d9d9d9)',
                            resize: 'vertical',
                        }}
                        data-testid="projeto-relatorio-bugs-prompt"
                        aria-label="Prompt de correção em Markdown"
                    />
                </>
            )}
        </Modal>
    );
}
