'use client';

import { confirmDialog } from '@/lib/feedback/confirmDialog';

import { message } from '@/lib/feedback/message';

import React, { useState, useMemo, useCallback } from 'react';
import dynamic from 'next/dynamic';
/**
 * Listagem de code reviews do projeto (`/projetos/[id]/qualidade/code-reviews`).
 * FRONT-S2-02 — extraído de `app/(dashboard)/projetos/[id]/qualidade/code-reviews/page.tsx`.
 * Template §3: `DetailPageLayout` + `fetchState`.
 */

import { CheckCircle2, Clock, Code, Filter, Menu, RefreshCw } from 'lucide-react';
import {
    Alert,
    Badge,
    Button,
    Col,
    Collapse,
    DatePicker,
    Modal,
    Row,
    Select,
    Space,
    Tooltip,
    Typography,
} from 'antd';
import { ICON_SIZE_MD } from '@/components/icons';
import { LazyExportButton } from '@/components/lazy';
import { LazyDataTable } from '@/components/lazy';
import type { ColumnsType } from 'antd/es/table';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useResponsiveModalProps } from '@/hooks/useResponsiveModalProps';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { listingTableVirtualScrollProps } from '@/lib/listings/listingTableVirtualScrollProps';
import type { Dayjs } from 'dayjs';
import btnHeaderStyles from '@/components/ui/buttons/ButtonHeaderIcon/ButtonHeaderIcon.module.scss';
import { useParams, useRouter } from 'next/navigation';
import ProjetoLayout from '@/components/layouts/ProjetoLayout';
import { DetailPageLayout } from '@/components/layouts/DetailPageLayout';
import MetricsGrid from '@/components/layouts/MetricsGrid';
import MetricCard from '@/components/layouts/MetricCard';
import ContentCard from '@/components/layouts/ContentCard';
import { FormGroup } from '@/components/form';
import { OperativeRouteHint } from '@/components/layouts/OperativeRouteHint/OperativeRouteHint';
import { ButtonHeaderIcon } from '@/components/ui';
import type { DetailPageFetchState } from '@/components/layouts/DetailPageLayout';
import { detailPageQueryErrorSubTitle } from '@/lib/utils/detailPageQueryErrorSubTitle';
import { getCodeReviewPrioridadeTag, getCodeReviewStatusTag } from './codeReviewDisplay';
import type { ProjetoCodeReview } from './types';
import { FiltrosModalFooterPadrao,
    ListPageCreateFloatButton} from '@/components/listings';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import { queryKeys } from '@/lib/cache/queryKeys';

const ModalOpcoesCodeReview = dynamic(
    () => import('./ModalOpcoesCodeReview').then((m) => m.ModalOpcoesCodeReview),
    { ssr: false },
);
const CodeReviewDetalhesModal = dynamic(
    () => import('./CodeReviewDetalhesModal').then((m) => m.CodeReviewDetalhesModal),
    { ssr: false },
);

const { RangePicker } = DatePicker;

const STATUS_CR_LABEL: Record<string, string> = {
    pendente: 'Pendente',
    em_revisao: 'Em revisão',
    aprovado: 'Aprovado',
    rejeitado: 'Rejeitado',
    alteracoes_solicitadas: 'Alterações solicitadas'};

const PRIORIDADE_CR_LABEL: Record<string, string> = {
    baixa: 'Baixa',
    media: 'Média',
    alta: 'Alta',
    critica: 'Crítica'};
const { Text } = Typography;

function routeSegmentId(params: ReturnType<typeof useParams>): string {
    const raw = params?.id;
    if (typeof raw === 'string') return raw;
    if (Array.isArray(raw)) return raw[0] ?? '';
    return '';
}

export function ProjetoCodeReviewsScreen() {
    const params = useParams();
    const router = useRouter();
    const projetoId = routeSegmentId(params);
    const { canEditar, permsLoading } = useProjetoWriteGates();
    const [selectedReview, setSelectedReview] = useState<ProjetoCodeReview | null>(null);
    const [modalDetalhes, setModalDetalhes] = useState(false);
    const [filtroStatus, setFiltroStatus] = useState<string>('');
    const [filtroPrioridade, setFiltroPrioridade] = useState<string>('');
    const [periodo, setPeriodo] = useState<[Dayjs, Dayjs] | null>(null);
    const [filtrosModalOpen, setFiltrosModalOpen] = useState(false);
    const [draftFiltroStatus, setDraftFiltroStatus] = useState('');
    const [draftFiltroPrioridade, setDraftFiltroPrioridade] = useState('');
    const [draftPeriodo, setDraftPeriodo] = useState<[Dayjs, Dayjs] | null>(null);
    const [opcoesItem, setOpcoesItem] = useState<ProjetoCodeReview | null>(null);
    const filtrosModalLayout = useResponsiveModalProps();

    const {
        data: codeReviewsData,
        isLoading,
        isError: codeReviewsQueryIsError,
        error: codeReviewsQueryError,
        refetch} = useQueryCache<{ data: ProjetoCodeReview[] }>({
        queryKey: queryKeys.qa.codeReviews.listFiltered(projetoId, filtroStatus, filtroPrioridade, periodo),
        endpoint: API_ENDPOINTS.qa?.codeReviews?.index || '/api/qa/code-reviews',
        params: {
            ...(filtroStatus && { status: filtroStatus }),
            ...(filtroPrioridade && { prioridade: filtroPrioridade }),
            ...(periodo && {
                data_inicio: periodo[0].format('YYYY-MM-DD'),
                data_fim: periodo[1].format('YYYY-MM-DD')})},
        staleTime: 1 * 60 * 1000,
        gcTime: 5 * 60 * 1000,
        enabled: Boolean(projetoId.trim())});

    const codeReviews = useMemo(() => codeReviewsData?.data ?? [], [codeReviewsData?.data]);

    const handleAprovar = async (_review: ProjetoCodeReview) => {
        try {
            message.success('Code review aprovado!');
            refetch();
        } catch {
            message.error('Erro ao aprovar code review');
        }
    };

    const handleRejeitar = async (review: ProjetoCodeReview) => {
        confirmDialog({
            title: 'Confirmar rejeição',
            content: `Deseja realmente rejeitar o code review "${review.titulo}"?`,
            okText: 'Rejeitar',
            okType: 'danger',
            cancelText: 'Cancelar',
            onOk: async () => {
                try {
                    message.success('Code review rejeitado');
                    refetch();
                } catch {
                    message.error('Erro ao rejeitar code review');
                }
            }});
    };

    const columns: ColumnsType<ProjetoCodeReview> = [
        {
            title: 'Título',
            dataIndex: 'titulo',
            key: 'titulo',
            sorter: (a, b) => String(a.titulo ?? '').localeCompare(String(b.titulo ?? ''), 'pt'),
            render: (text: string) => <span style={{ fontWeight: 600, color: '#2c3e50' }}>{text}</span>},
        {
            title: 'Projeto',
            key: 'projeto',
            sorter: (a, b) =>
                String(a.projeto?.nome ?? '').localeCompare(String(b.projeto?.nome ?? ''), 'pt'),
            render: (_: unknown, record: ProjetoCodeReview) => <span>{record.projeto?.nome || '-'}</span>},
        {
            title: 'Autor',
            key: 'autor',
            sorter: (a, b) => String(a.autor?.nome ?? '').localeCompare(String(b.autor?.nome ?? ''), 'pt'),
            render: (_: unknown, record: ProjetoCodeReview) => <span>{record.autor?.nome || '-'}</span>},
        {
            title: 'Revisor',
            key: 'revisor',
            sorter: (a, b) =>
                String(a.revisor?.nome ?? '').localeCompare(String(b.revisor?.nome ?? ''), 'pt'),
            render: (_: unknown, record: ProjetoCodeReview) => <span>{record.revisor?.nome || '-'}</span>},
        {
            title: 'Status',
            dataIndex: 'status',
            key: 'status',
            sorter: (a, b) => String(a.status ?? '').localeCompare(String(b.status ?? ''), 'pt'),
            render: (status: string) => getCodeReviewStatusTag(status)},
        {
            title: 'Prioridade',
            dataIndex: 'prioridade',
            key: 'prioridade',
            sorter: (a, b) =>
                String(a.prioridade ?? '').localeCompare(String(b.prioridade ?? ''), 'pt'),
            render: (prioridade: string) => getCodeReviewPrioridadeTag(prioridade)},
        {
            title: 'Mudanças',
            key: 'mudancas',
            sorter: (a, b) =>
                (a.linhas_adicionadas ?? 0) +
                (a.linhas_removidas ?? 0) -
                ((b.linhas_adicionadas ?? 0) + (b.linhas_removidas ?? 0)),
            render: (_: unknown, record: ProjetoCodeReview) => (
                <div style={{ fontSize: 12 }}>
                    <div style={{ color: '#52c41a' }}>+{record.linhas_adicionadas || 0}</div>
                    <div style={{ color: '#ff4d4f' }}>-{record.linhas_removidas || 0}</div>
                    <div style={{ color: '#666' }}>{record.arquivos_alterados || 0} arquivos</div>
                </div>
            )},
        {
            title: '',
            key: 'menu',
            width: 56,
            align: 'center',
            onCell: () => ({ onClick: (e: React.MouseEvent) => e.stopPropagation() }),
            render: (_: unknown, record: ProjetoCodeReview) => (
                <Button
                    type="text"
                    size="small"
                    icon={<Menu />}
                    onClick={() => setOpcoesItem(record)}
                    aria-label="Opções"
                />
            )},
    ];

    const reviewsPendentes = codeReviews.filter((r: any) => r.status === 'pendente').length;
    const reviewsEmRevisao = codeReviews.filter((r: any) => r.status === 'em_revisao').length;
    const reviewsAprovados = codeReviews.filter((r: any) => r.status === 'aprovado').length;
    const totalLinhas = codeReviews.reduce((sum, r) => sum + (r.linhas_adicionadas || 0), 0);

    const closeDetalhes = () => {
        setModalDetalhes(false);
        setSelectedReview(null);
    };

    const idValid = Boolean(projetoId.trim());

    const fetchState: DetailPageFetchState = useMemo(() => {
        if (!idValid) return 'not_found';
        if (codeReviewsQueryIsError && !codeReviewsData) return 'error';
        if (isLoading && !codeReviewsData) return 'loading';
        return 'ready';
    }, [idValid, codeReviewsQueryIsError, codeReviewsData, isLoading]);

    const codeReviewsQueryErr =
        codeReviewsQueryError instanceof Error
            ? codeReviewsQueryError
            : codeReviewsQueryError
              ? new Error(String(codeReviewsQueryError))
              : null;

    const listErrorSubTitle = useMemo(
        () => detailPageQueryErrorSubTitle(codeReviewsQueryError),
        [codeReviewsQueryError]
    );

    const filtrosAtivosCount = useMemo(() => {
        let n = 0;
        if (filtroStatus) n += 1;
        if (filtroPrioridade) n += 1;
        if (periodo && periodo[0] && periodo[1]) n += 1;
        return n;
    }, [filtroStatus, filtroPrioridade, periodo]);
    const filtrosComAlgumAtivo = filtrosAtivosCount > 0;

    const resumoFiltrosAplicados = useMemo(() => {
        const partes: string[] = [];
        if (filtroStatus) partes.push(`Status: ${STATUS_CR_LABEL[filtroStatus] ?? filtroStatus}`);
        if (filtroPrioridade) {
            partes.push(`Prioridade: ${PRIORIDADE_CR_LABEL[filtroPrioridade] ?? filtroPrioridade}`);
        }
        if (periodo?.[0] && periodo[1]) {
            partes.push(
                `Período: ${periodo[0].format('DD/MM/YYYY')} — ${periodo[1].format('DD/MM/YYYY')}`
            );
        }
        return partes.length ? partes.join(' · ') : '';
    }, [filtroStatus, filtroPrioridade, periodo]);

    const limparTodosFiltros = useCallback(() => {
        setFiltroStatus('');
        setFiltroPrioridade('');
        setPeriodo(null);
        setDraftFiltroStatus('');
        setDraftFiltroPrioridade('');
        setDraftPeriodo(null);
    }, []);

    const abrirModalFiltros = useCallback(() => {
        setDraftFiltroStatus(filtroStatus);
        setDraftFiltroPrioridade(filtroPrioridade);
        setDraftPeriodo(periodo);
        setFiltrosModalOpen(true);
    }, [filtroStatus, filtroPrioridade, periodo]);

    const reporRascunhoFiltros = useCallback(() => {
        setDraftFiltroStatus('');
        setDraftFiltroPrioridade('');
        setDraftPeriodo(null);
    }, []);

    const aplicarFiltrosModal = useCallback(() => {
        if (draftPeriodo) {
            const [ini, fim] = draftPeriodo;
            if (!ini || !fim) {
                message.warning('Selecione início e fim do período ou limpe o intervalo no modal.');
                return;
            }
            if (fim.isBefore(ini, 'day')) {
                message.warning('A data fim deve ser igual ou posterior à data de início.');
                return;
            }
        }
        setFiltroStatus(draftFiltroStatus);
        setFiltroPrioridade(draftFiltroPrioridade);
        setPeriodo(draftPeriodo);
        setFiltrosModalOpen(false);
    }, [draftFiltroStatus, draftFiltroPrioridade, draftPeriodo]);

    return (
        <ProjetoLayout
            projetoId={projetoId}
            pageTitle="Code reviews"
            showPageTitleIcon={false}
            titleSection="Code reviews"
            headerAction={
                fetchState === 'ready' ? (
                        <Space wrap size={8} align="center">
                            <Tooltip
                                title={
                                    filtrosComAlgumAtivo
                                        ? `Filtros ativos (${filtrosAtivosCount}) — abrir para alterar status, prioridade ou período`
                                        : 'Definir status, prioridade e intervalo de datas na listagem'
                                }
                            >
                                <span style={{ display: 'inline-block' }}>
                                <Badge dot={filtrosComAlgumAtivo} color="geekblue">
                                    <ButtonHeaderIcon
                                        data-testid="projeto-qualidade-code-reviews-abrir-filtros"
                                        icon={<Filter size={ICON_SIZE_MD} aria-hidden />}
                                        title={
                                            filtrosAtivosCount > 0
                                                ? `Filtros (${filtrosAtivosCount})`
                                                : 'Filtros'
                                        }
                                        aria-label="Abrir filtros de code reviews"
                                        aria-expanded={filtrosModalOpen}
                                        aria-haspopup="dialog"
                                        onClick={abrirModalFiltros}
                                        className={btnHeaderStyles.btnHeaderIcon}
                                    />
                                </Badge>
                                </span>
                            </Tooltip>
                            <Tooltip title="Exportar code reviews visíveis (Excel, PDF, CSV ou JSON)">
                                <span style={{ display: 'inline-block' }}>
                                    <LazyExportButton
                                        data={codeReviews as unknown as Record<string, unknown>[]}
                                        columns={[
                                            { key: 'titulo', label: 'Título' },
                                            { key: 'status', label: 'Status' },
                                            { key: 'prioridade', label: 'Prioridade' },
                                        ]}
                                        filename="code-reviews"
                                        iconOnly
                                        title="Exportar code reviews"
                                        size="large"
                                        exportMenuMode="modal"
                                        className={btnHeaderStyles.btnHeaderIcon}
                                    />
                                </span>
                            </Tooltip>
                        </Space>
                    ) : undefined
            }
        >
        <DetailPageLayout
            breadcrumbItems={[
                { title: 'Projetos', path: '/projetos' },
                ...(idValid
                    ? [
                          { title: 'Projeto', path: `/projetos/${projetoId}` },
                          {
                              title: 'Code reviews',
                              path: `/projetos/${projetoId}/qualidade/code-reviews`},
                      ]
                    : [{ title: 'Code reviews' }]),
            ]}
            header={{
                title: 'Code reviews',
                titleContent: '',
                description: 'Gerenciar revisões de código e pull requests — refine o recorte com Filtros no cabeçalho.',
            }}
            fetchState={fetchState}
            error={codeReviewsQueryErr}
            onRetry={() => void refetch()}
            errorSubTitle={listErrorSubTitle}
            notFoundTitle="Projeto inválido"
            notFoundSubTitle="O identificador do projeto está em falta ou é inválido na rota."
            notFoundExtra={
                <Button type="primary" onClick={() => router.push('/projetos')}>
                    Voltar aos projetos
                </Button>
            }
            wrapChildrenInCard={false}
        >
            {fetchState === 'ready' ? (
                <OperativeRouteHint
                    message="Decisão de revisão com critérios visíveis"
                    description="Antes de aprovar, confirme segurança, regressão e aderência a padrões do projeto. Use Filtros no cabeçalho para status, prioridade e período; use o checklist abaixo como referência — marque mentalmente cada ponto ou registre no comité."
                />
            ) : null}

            {fetchState === 'ready' ? (
                <ContentCard title="Checklist objetivo de code review" style={{ marginBottom: 24 }}>
                    <Collapse
                        defaultActiveKey={['seg']}
                        items={[
                            {
                                key: 'seg',
                                label: 'Segurança e dados',
                                children: (
                                    <Text type="secondary">
                                        Entradas validadas, sem segredos em log, queries parametrizadas,
                                        uploads seguros, autorização por perfil.
                                    </Text>
                                )},
                            {
                                key: 'perf',
                                label: 'Performance e fiabilidade',
                                children: (
                                    <Text type="secondary">
                                        N+1 evitado onde crítico, timeouts e retries onde integra externo,
                                        impacto em jobs/filas conhecido.
                                    </Text>
                                )},
                            {
                                key: 'ux',
                                label: 'UX e acessibilidade',
                                children: (
                                    <Text type="secondary">
                                        Estados de erro/recuperação, foco e contraste em componentes
                                        tocados, mensagens acionáveis.
                                    </Text>
                                )},
                        ]}
                    />
                </ContentCard>
            ) : null}

            <MetricsGrid columns={4} style={{ marginBottom: 24 }}>
                <MetricCard
                    icon={<Clock size={ICON_SIZE_MD} aria-hidden />}
                    label="Pendentes"
                    value={reviewsPendentes}
                    variant="planejamento"
                />
                <MetricCard
                    icon={<RefreshCw size={ICON_SIZE_MD} aria-hidden />}
                    label="Em Revisão"
                    value={reviewsEmRevisao}
                    variant="emAndamento"
                />
                <MetricCard
                    icon={<CheckCircle2 size={ICON_SIZE_MD} aria-hidden />}
                    label="Aprovados"
                    value={reviewsAprovados}
                    variant="concluidos"
                />
                <MetricCard
                    icon={<Code size={ICON_SIZE_MD} aria-hidden />}
                    label="Total Linhas"
                    value={totalLinhas}
                    variant="projetos"
                />
            </MetricsGrid>

            <Modal
                title="Filtrar code reviews"
                data-testid="projeto-qualidade-code-reviews-filtros-modal"
                open={filtrosModalOpen}
                onCancel={() => setFiltrosModalOpen(false)}
                width={filtrosModalLayout.width ?? 720}
                centered={filtrosModalLayout.centered}
                styles={filtrosModalLayout.styles}
                footer={
                    <FiltrosModalFooterPadrao
                        onLimparTodos={reporRascunhoFiltros}
                        onFechar={() => setFiltrosModalOpen(false)}
                        showFiltrarPrimary
                        onFiltrar={aplicarFiltrosModal}
                        dataTestIdLimparTodos="projeto-qualidade-code-reviews-filtros-modal-limpar-todos"
                    />
                }
                destroyOnHidden
                keyboard
                focusTriggerAfterClose
            >
                <Row gutter={16}>
                    <Col xs={24} sm={8}>
                        <FormGroup label="Status">
                            <Select
                                placeholder="Todos"
                                style={{ width: '100%' }}
                                allowClear
                                value={draftFiltroStatus || undefined}
                                onChange={(v) => setDraftFiltroStatus(v ?? '')}
                            >
                                <Select.Option value="pendente">Pendente</Select.Option>
                                <Select.Option value="em_revisao">Em Revisão</Select.Option>
                                <Select.Option value="aprovado">Aprovado</Select.Option>
                                <Select.Option value="rejeitado">Rejeitado</Select.Option>
                                <Select.Option value="alteracoes_solicitadas">Alterações Solicitadas</Select.Option>
                            </Select>
                        </FormGroup>
                    </Col>
                    <Col xs={24} sm={8}>
                        <FormGroup label="Prioridade">
                            <Select
                                placeholder="Todas"
                                style={{ width: '100%' }}
                                allowClear
                                value={draftFiltroPrioridade || undefined}
                                onChange={(v) => setDraftFiltroPrioridade(v ?? '')}
                            >
                                <Select.Option value="baixa">Baixa</Select.Option>
                                <Select.Option value="media">Média</Select.Option>
                                <Select.Option value="alta">Alta</Select.Option>
                                <Select.Option value="critica">Crítica</Select.Option>
                            </Select>
                        </FormGroup>
                    </Col>
                    <Col xs={24} sm={8}>
                        <FormGroup label="Período (datas)">
                            <RangePicker
                                style={{ width: '100%' }}
                                value={draftPeriodo}
                                onChange={(dates) => setDraftPeriodo(dates as [Dayjs, Dayjs] | null)}
                            />
                        </FormGroup>
                    </Col>
                </Row>
            </Modal>

            {filtrosComAlgumAtivo ? (
                <Alert
                    type="info"
                    showIcon
                    style={{ marginBottom: 16 }}
                    message={`Filtros aplicados (${filtrosAtivosCount})`}
                    description={
                        <>
                            {resumoFiltrosAplicados}
                            <Button type="link" onClick={limparTodosFiltros} style={{ paddingLeft: 8 }}>
                                Limpar filtros
                            </Button>
                        </>
                    }
                />
            ) : null}

            <div style={{ marginTop: filtrosComAlgumAtivo ? 0 : undefined }}>
                <LazyDataTable
                    columns={columns}
                    data={codeReviews}
                    loading={isLoading}
                    onRefresh={refetch}
                    {...listingTableVirtualScrollProps(codeReviews.length)}
                    onRow={(record: unknown) => ({
                        onClick: () => setOpcoesItem(record as ProjetoCodeReview),
                        style: { cursor: 'pointer' },
                    })}
                />
            </div>

            <ModalOpcoesCodeReview
                open={opcoesItem !== null}
                onClose={() => setOpcoesItem(null)}
                item={opcoesItem}
                onVerDetalhes={(item) => {
                    setOpcoesItem(null);
                    setSelectedReview(item);
                    setModalDetalhes(true);
                }}
                onAprovar={handleAprovar}
                onRejeitar={handleRejeitar}
            />

            <CodeReviewDetalhesModal open={modalDetalhes} review={selectedReview} onClose={closeDetalhes} />

            {fetchState === 'ready' && idValid && !permsLoading && canEditar ? (
                <ListPageCreateFloatButton
                    data-testid="projeto-code-reviews-fab-novo"
                    tooltip={{
                        title: 'Novo code review — refine a listagem com Filtros no cabeçalho',
                    }}
                    onClick={() => router.push(`/projetos/${projetoId}/qualidade/code-reviews/create`)}
                />
            ) : null}
        </DetailPageLayout>
        </ProjetoLayout>
    );
}
