'use client';

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/navigation';
import { Alert, Button, Form, Result, Spin, Tabs, Tag, Typography } from 'antd';
import { FileText, Flag, GitBranch, Layers, ListOrdered } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import ContentCard from '@/components/layouts/ContentCard';
import MetricCard from '@/components/layouts/MetricCard';
import MetricsGrid from '@/components/layouts/MetricsGrid';
import ProjetoLayout from '@/components/layouts/ProjetoLayout';
import { DetailPrintSheet } from '@/components/layouts/DetailPrint';
import {
    DetailOpcoesPresentation,
    useDetailOpcoesDesktopRail,
} from '@/components/layouts/DetailOpcoesSidePanel';
import { ListingPageOptionsButton } from '@/components/listings';
import { ModuleRelatedLinksPanel } from '@/components/navigation/ModuleRelatedLinksPanel';
import { useMutationCache } from '@/hooks/useMutationCache';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useQueryClient } from '@tanstack/react-query';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { queryKeys } from '@/lib/cache/queryKeys';
import apiClient from '@/lib/api/client';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { message } from '@/lib/feedback/message';
import { confirmDialog } from '@/lib/feedback/confirmDialog';
import { projetosProjetoCanonical } from '@/lib/routes/projetosProjetoCanonical';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import { CasoUsoPassosFields, CasoUsoSpecFields } from './CasoUsoFormFields';
import { buildCasoUsoDetalheOpcoesGroups } from './buildCasoUsoDetalheOpcoesGroups';
import {
    CASO_USO_STATUS_COLOR,
    labelCasoUsoNivel,
    labelCasoUsoPrioridade,
    labelCasoUsoStatus,
} from './casoUsoDisplay';
import type { CasoUso, CasoUsoGrafo, CasoUsoPasso } from './types';
import styles from './ProjetoCasoUsoFormScreen.module.scss';

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

const RELATED_SURFACE = 'projetos.planejamento.casos-uso.list' as const;

export type ProjetoCasoUsoFormScreenProps = {
    projetoId: string;
    casoUsoId?: string;
};

type Envelope<T> = { data: T };

/** Gestão do caso de uso — header só no ProjetoLayout (planejamento). */
export function ProjetoCasoUsoFormScreen({ projetoId, casoUsoId }: ProjetoCasoUsoFormScreenProps) {
    const router = useRouter();
    const [form] = Form.useForm();
    const queryClient = useQueryClient();
    const { canEditar, canExcluir, tooltipSemPermissao } = useProjetoWriteGates();
    const isDesktopOpcoesRail = useDetailOpcoesDesktopRail();
    const [opcoesOpen, setOpcoesOpen] = useState(false);
    const [statusPending, setStatusPending] = useState(false);
    const listaPath = projetosProjetoCanonical.planejamentoCasosDeUso(projetoId);
    const umlHref = projetosProjetoCanonical.planejamentoCasosDeUsoDiagrama(projetoId);

    const {
        data: caso,
        isLoading,
        isError,
        isFetched,
        refetch,
    } = useQueryCache<CasoUso>({
        queryKey: queryKeys.projetos.casoUso(projetoId, casoUsoId ?? 'novo'),
        endpoint: casoUsoId ? API_ENDPOINTS.projetos.casosUso.show(projetoId, casoUsoId) : '',
        enabled: Boolean(casoUsoId),
        unwrapApiEnvelope: true,
    });

    const { data: grafo, refetch: refetchGrafo } = useQueryCache<CasoUsoGrafo>({
        queryKey: queryKeys.projetos.casosUsoDiagrama(projetoId, 'atividade', casoUsoId ?? ''),
        endpoint: casoUsoId ? API_ENDPOINTS.projetos.casosUso.diagramaCaso(projetoId, casoUsoId) : '',
        enabled: Boolean(casoUsoId),
        unwrapApiEnvelope: true,
    });

    const { mutateAsync: salvar, isPending } = useMutationCache<Envelope<CasoUso>, Record<string, unknown>>({
        endpoint: casoUsoId ? API_ENDPOINTS.projetos.casosUso.update(projetoId, casoUsoId) : '',
        method: 'PUT',
        invalidateQueries: [
            queryKeys.projetos.casosUso(projetoId),
            queryKeys.projetos.casosUsoResumo(projetoId),
            ...(casoUsoId ? [queryKeys.projetos.casoUso(projetoId, casoUsoId)] : []),
        ],
    });

    const { mutateAsync: salvarGrafo } = useMutationCache({
        endpoint: casoUsoId ? API_ENDPOINTS.projetos.casosUso.diagramaCaso(projetoId, casoUsoId) : '',
        method: 'PUT',
        invalidateQueries: casoUsoId
            ? [queryKeys.projetos.casosUsoDiagrama(projetoId, 'atividade', casoUsoId)]
            : [],
    });

    useEffect(() => {
        if (!caso) {
            return;
        }
        form.setFieldsValue({
            titulo: caso.titulo,
            objetivo: caso.objetivo,
            gatilho: caso.gatilho,
            pre_condicoes: caso.pre_condicoes,
            pos_condicoes_sucesso: caso.pos_condicoes_sucesso,
            pos_condicoes_falha: caso.pos_condicoes_falha,
            escopo: caso.escopo,
            frequencia: caso.frequencia,
            observacoes: caso.observacoes,
            nivel: caso.nivel ?? 'primario',
            prioridade: caso.prioridade ?? 'media',
            ator_principal_livre: caso.ator_principal_livre,
            passos: (caso.passos?.length ? caso.passos : []) as CasoUsoPasso[],
        });
    }, [caso, form]);

    const bloqueado = caso?.status === 'aprovado' || caso?.status === 'obsoleto' || !canEditar;
    const qtdPassos = caso?.passos_count ?? caso?.passos?.length ?? 0;

    const invalidateCaso = useCallback(async () => {
        await queryClient.invalidateQueries({ queryKey: queryKeys.projetos.casosUso(projetoId) });
        await queryClient.invalidateQueries({ queryKey: queryKeys.projetos.casosUsoResumo(projetoId) });
        if (casoUsoId) {
            await queryClient.invalidateQueries({ queryKey: queryKeys.projetos.casoUso(projetoId, casoUsoId) });
        }
        await refetch();
    }, [queryClient, projetoId, casoUsoId, refetch]);

    const onFinish = async (values: Record<string, unknown>) => {
        try {
            await salvar(values);
            message.success('Caso de uso salvo.');
        } catch (e) {
            message.error(getLaravelApiErrorMessage(e));
        }
    };

    const postStatus = async (kind: 'aprovar' | 'reabrir' | 'obsoletar') => {
        if (!casoUsoId) {
            return;
        }
        const url =
            kind === 'aprovar'
                ? API_ENDPOINTS.projetos.casosUso.aprovar(projetoId, casoUsoId)
                : kind === 'reabrir'
                  ? API_ENDPOINTS.projetos.casosUso.reabrir(projetoId, casoUsoId)
                  : API_ENDPOINTS.projetos.casosUso.obsoletar(projetoId, casoUsoId);
        setStatusPending(true);
        try {
            await apiClient.post(url);
            message.success(
                kind === 'aprovar'
                    ? 'Caso de uso aprovado.'
                    : kind === 'reabrir'
                      ? 'Caso de uso reaberto para revisão.'
                      : 'Caso de uso marcado como obsoleto.',
            );
            await invalidateCaso();
        } catch (e) {
            message.error(getLaravelApiErrorMessage(e));
        } finally {
            setStatusPending(false);
        }
    };

    const excluir = async () => {
        if (!casoUsoId) {
            return;
        }
        try {
            await apiClient.delete(API_ENDPOINTS.projetos.casosUso.destroy(projetoId, casoUsoId));
            message.success('Caso de uso excluído.');
            router.push(listaPath);
        } catch (e) {
            message.error(getLaravelApiErrorMessage(e));
        }
    };

    const opcoesGroups = useMemo(() => {
        if (!caso) {
            return [];
        }
        return buildCasoUsoDetalheOpcoesGroups({
            caso,
            canEditar,
            canExcluir,
            bloqueado,
            salvarPending: isPending,
            statusPending,
            tooltipSemPermissao,
            handlers: {
                onSalvar: () => form.submit(),
                onAprovar: () =>
                    void confirmDialog({
                        title: 'Aprovar caso de uso?',
                        content: 'É necessário ter pelo menos um passo principal. Depois de aprovado, a edição exige reabrir.',
                        okText: 'Aprovar',
                        cancelText: 'Cancelar',
                        onOk: () => postStatus('aprovar'),
                    }),
                onReabrir: () =>
                    void confirmDialog({
                        title: 'Reabrir para revisão?',
                        content: 'O caso de uso voltará a ficar editável.',
                        okText: 'Reabrir',
                        cancelText: 'Cancelar',
                        onOk: () => postStatus('reabrir'),
                    }),
                onObsoletar: () =>
                    void confirmDialog({
                        title: 'Obsoletar este caso de uso?',
                        content: 'Ele deixará de fazer parte do conjunto ativo.',
                        okText: 'Obsoletar',
                        cancelText: 'Cancelar',
                        onOk: () => postStatus('obsoletar'),
                    }),
                onExcluir: () =>
                    void confirmDialog({
                        title: 'Excluir este caso de uso?',
                        content: 'Esta ação remove o registro da listagem. Não é possível desfazer pelo painel.',
                        okText: 'Excluir',
                        okButtonProps: { danger: true },
                        cancelText: 'Cancelar',
                        onOk: () => excluir(),
                    }),
                onVoltarLista: () => router.push(listaPath),
                umlHref,
            },
        });
    }, [
        caso,
        canEditar,
        canExcluir,
        bloqueado,
        isPending,
        statusPending,
        tooltipSemPermissao,
        form,
        listaPath,
        umlHref,
        router,
        projetoId,
        casoUsoId,
    ]);

    const headerActions = !isDesktopOpcoesRail ? (
        <ListingPageOptionsButton
            data-testid="projeto-caso-uso-detalhe-mais-opcoes"
            expanded={opcoesOpen}
            ariaLabel="Opções do caso de uso"
            tooltipTitle="Ações do registro"
            onClick={() => setOpcoesOpen(true)}
        />
    ) : null;

    return (
        <ProjetoLayout
            projetoId={projetoId}
            pageTitle={caso?.codigo ?? 'Caso de uso'}
            showPageTitleIcon={false}
            titleSection="Casos de uso"
            headerAction={headerActions}
        >
            <Form form={form} layout="vertical" onFinish={onFinish} disabled={!canEditar}>
                {isLoading ? (
                    <div style={{ display: 'flex', justifyContent: 'center', padding: 48 }}>
                        <Spin />
                    </div>
                ) : null}

                {isError ? (
                    <Result
                        status="error"
                        title="Não foi possível carregar o caso de uso"
                        extra={
                            <Button type="primary" onClick={() => void refetch()}>
                                Tentar novamente
                            </Button>
                        }
                    />
                ) : null}

                {isFetched && !caso && !isLoading && !isError ? (
                    <Result
                        status="404"
                        title="Caso de uso não encontrado"
                        subTitle="O registro pode ter sido removido ou o endereço está incorreto."
                        extra={<Button onClick={() => router.push(listaPath)}>Voltar à listagem</Button>}
                    />
                ) : null}

                {caso ? (
                    <div className={styles.page}>
                        <section className={styles.hero} aria-labelledby="caso-uso-titulo">
                            <div className={styles.heroMain}>
                                <span className={styles.heroKicker}>{caso.codigo}</span>
                                <Typography.Title id="caso-uso-titulo" level={2} className={styles.heroTitle}>
                                    {caso.titulo}
                                </Typography.Title>
                                <div className={styles.heroMeta}>
                                    <Tag color={CASO_USO_STATUS_COLOR[caso.status]}>
                                        {labelCasoUsoStatus(caso.status)}
                                    </Tag>
                                    <Tag>{labelCasoUsoPrioridade(caso.prioridade)}</Tag>
                                    <Tag>{labelCasoUsoNivel(caso.nivel)}</Tag>
                                    {caso.ator_principal_livre ? <Tag>{caso.ator_principal_livre}</Tag> : null}
                                </div>
                                {caso.objetivo ? (
                                    <Typography.Paragraph className={styles.heroObjetivo} ellipsis={{ rows: 3 }}>
                                        {caso.objetivo}
                                    </Typography.Paragraph>
                                ) : null}
                            </div>
                        </section>

                        <MetricsGrid columns={4} style={{ marginBottom: 0, gap: 15 }}>
                            <MetricCard
                                icon={<Layers size={ICON_SIZE_MD} />}
                                label="Status"
                                value={labelCasoUsoStatus(caso.status)}
                                variant="projetos"
                            />
                            <MetricCard
                                icon={<Flag size={ICON_SIZE_MD} />}
                                label="Prioridade"
                                value={labelCasoUsoPrioridade(caso.prioridade)}
                                variant="planejamento"
                            />
                            <MetricCard
                                icon={<FileText size={ICON_SIZE_MD} />}
                                label="Nível"
                                value={labelCasoUsoNivel(caso.nivel)}
                                variant="backlog"
                            />
                            <MetricCard
                                icon={<ListOrdered size={ICON_SIZE_MD} />}
                                label="Passos"
                                value={qtdPassos}
                                subvalue={qtdPassos === 0 ? 'Inclua o fluxo principal' : 'Fluxo documentado'}
                                variant={qtdPassos === 0 ? 'pausados' : 'concluidos'}
                            />
                        </MetricsGrid>

                        {!canEditar ? (
                            <Alert
                                type="info"
                                showIcon
                                message="Consulta"
                                description="Você pode ver a especificação. A edição exige permissão de projeto."
                            />
                        ) : null}
                        {caso.status === 'aprovado' ? (
                            <Alert
                                type="success"
                                showIcon
                                message="Aprovado"
                                description="Use Reabrir no painel de opções para alterar a especificação ou o diagrama."
                            />
                        ) : null}
                        {caso.status === 'obsoleto' ? (
                            <Alert type="warning" showIcon message="Obsoleto" description="Este caso de uso não faz mais parte do conjunto ativo." />
                        ) : null}

                        <div className={styles.split}>
                            <div className={styles.mainPanel}>
                                <Tabs
                                    className={styles.premiumTabs}
                                    items={[
                                        {
                                            key: 'especificacao',
                                            label: 'Especificação',
                                            icon: <FileText size={16} aria-hidden />,
                                            children: <CasoUsoSpecFields disabled={bloqueado} />,
                                        },
                                        {
                                            key: 'fluxo',
                                            label: 'Fluxo',
                                            icon: <ListOrdered size={16} aria-hidden />,
                                            children: <CasoUsoPassosFields disabled={bloqueado} />,
                                        },
                                        {
                                            key: 'diagrama',
                                            label: 'Diagrama',
                                            icon: <GitBranch size={16} aria-hidden />,
                                            children: (
                                                <CasoUsoFlowCanvas
                                                    grafo={grafo ?? { nodes: [], edges: [] }}
                                                    variant="atividade"
                                                    readOnly={bloqueado}
                                                    onSave={async (g) => {
                                                        try {
                                                            await salvarGrafo({ tipo: 'atividade', grafo: g });
                                                            message.success('Diagrama salvo.');
                                                            void refetchGrafo();
                                                        } catch (e) {
                                                            message.error(getLaravelApiErrorMessage(e));
                                                        }
                                                    }}
                                                />
                                            ),
                                        },
                                    ]}
                                />
                            </div>
                            <aside className={styles.sidebar}>
                                <ContentCard title="Resumo">
                                    <div className={styles.sidebarFact}>
                                        <span className={styles.sidebarFactLabel}>Código</span>
                                        <span className={styles.sidebarFactValue}>{caso.codigo}</span>
                                    </div>
                                    <div className={styles.sidebarFact}>
                                        <span className={styles.sidebarFactLabel}>Ator principal</span>
                                        <span className={styles.sidebarFactValue}>
                                            {caso.ator_principal_livre?.trim() || '—'}
                                        </span>
                                    </div>
                                    <div className={styles.sidebarFact}>
                                        <span className={styles.sidebarFactLabel}>Gatilho</span>
                                        <span className={styles.sidebarFactValue}>
                                            {caso.gatilho?.trim() || '—'}
                                        </span>
                                    </div>
                                    <div className={styles.sidebarFact}>
                                        <span className={styles.sidebarFactLabel}>Passos</span>
                                        <span className={styles.sidebarFactValue}>{qtdPassos}</span>
                                    </div>
                                </ContentCard>
                            </aside>
                        </div>

                        <ModuleRelatedLinksPanel
                            surfaceKey={RELATED_SURFACE}
                            variant="footer"
                            pagePrefix="projeto-planejamento-casos-uso-detalhe"
                            projetoId={projetoId}
                        />
                    </div>
                ) : null}
            </Form>

            {caso ? (
                <DetailPrintSheet
                    title="Caso de uso"
                    subtitle={`${caso.codigo} · ${caso.titulo}`}
                    status={labelCasoUsoStatus(caso.status)}
                    sections={[
                        {
                            title: 'Identificação',
                            rows: [
                                { label: 'Código', value: caso.codigo },
                                { label: 'Título', value: caso.titulo, fullWidth: true },
                                { label: 'Status', value: labelCasoUsoStatus(caso.status) },
                                { label: 'Prioridade', value: labelCasoUsoPrioridade(caso.prioridade) },
                                { label: 'Nível', value: labelCasoUsoNivel(caso.nivel) },
                                { label: 'Ator', value: caso.ator_principal_livre },
                            ],
                        },
                        {
                            title: 'Especificação',
                            rows: [
                                { label: 'Objetivo', value: caso.objetivo, fullWidth: true },
                                { label: 'Gatilho', value: caso.gatilho, fullWidth: true },
                                { label: 'Pré-condições', value: caso.pre_condicoes, fullWidth: true },
                                {
                                    label: 'Pós-condições (sucesso)',
                                    value: caso.pos_condicoes_sucesso,
                                    fullWidth: true,
                                },
                            ],
                        },
                    ]}
                />
            ) : null}

            {caso ? (
                <DetailOpcoesPresentation
                    open={opcoesOpen}
                    onClose={() => setOpcoesOpen(false)}
                    title="Opções do caso de uso"
                    subtitle={`${caso.codigo} · ${caso.titulo}`}
                    groups={opcoesGroups}
                    desktopSidePanel
                    loading={isPending || statusPending}
                    data-testid="projeto-caso-uso-detalhe-opcoes"
                    aria-label={`Opções do caso de uso ${caso.codigo}`}
                />
            ) : null}
        </ProjetoLayout>
    );
}
