'use client';

/**
 * Escopo inicial do site/produto — `/projetos/[id]/software/escopo`.
 *
 * Inclui herdar de outro projeto Waygest e importar rascunho a partir de URL externa.
 */

import { FileDown, Link2, Save } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import React, { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { Button, Form, Space, Spin, Tooltip } from 'antd';
import { message } from '@/lib/feedback/message';
import { notifyApiError } from '@/lib/feedback/notifyApiError';
import { confirmDialog } from '@/lib/feedback/confirmDialog';
import { FormTextarea } from '@/components/form';
import { FormActions as FormActionsWrapper } from '@/components/form';
import { useMobilePageActionBarRegistration } from '@/components/layouts/PageShellOptions';
import { useIsMobile } from '@/hooks/useIsMobile';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import { queryKeys } from '@/lib/cache/queryKeys';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { Projeto } from '@/types';
import ProjetoLayout from '@/components/layouts/ProjetoLayout';
import ContentCard from '@/components/layouts/ContentCard';
import { ButtonHeaderIcon } from '@/components/ui/buttons/ButtonHeaderIcon/ButtonHeaderIcon';
import btnHeaderStyles from '@/components/ui/buttons/ButtonHeaderIcon/ButtonHeaderIcon.module.scss';
import styles from './ProjetoSoftwareEscopoScreen.module.scss';
import { useProjetoBriefingFormGuard } from '@/features/projetos/hooks/useProjetoBriefingFormGuard';
import { resolveEscopoPlaceholder } from '@/features/projetos/lib/resolveAplicacaoReactTipologiaCopy';
import { useRegisterPlanejamentoWizardSave } from '@/components/layouts/ProjetoLayout/ProjetoPlanejamentoWizardContext';
import { ModalHerdarEscopoProjeto } from './ModalHerdarEscopoProjeto';
import { ModalImportarEscopoUrl } from './ModalImportarEscopoUrl';
import type { FormInstance } from 'antd';
import {
    ProjetoTipologicoSyncBanner,
    TIPOLOGICO_EMPTY_DOMAIN,
} from '@/features/projetos/projeto-tipologico-empty-state';

/** Precisa montar como filho do ProjetoLayout (provider do wizard mobile). */
function EscopoPlanejamentoWizardSaveBridge({
    form,
    canEditar,
    saving,
    onPersist,
}: {
    form: FormInstance;
    canEditar: boolean;
    saving: boolean;
    onPersist: (values: {
        termo_escopo?: string;
        premissas?: string;
        restricoes?: string;
    }) => Promise<unknown>;
}) {
    useRegisterPlanejamentoWizardSave({
        enabled: canEditar,
        canSave: canEditar && !saving,
        saving,
        saveLabel: 'Salvar',
        onSave: async () => {
            const values = await form.validateFields();
            await onPersist(values);
        },
    });
    return null;
}

type EscopoPreviewResponse = {
    success?: boolean;
    message?: string;
    termo_escopo?: string;
    projeto_origem?: { id: number; nome: string };
    titulo?: string | null;
    fonte?: string;
};

export function ProjetoSoftwareEscopoScreen() {
    const params = useParams();
    const id = params?.id as string;
    const isMobileLayout = useIsMobile();
    const { canEditar, tooltipSemPermissao } = useProjetoWriteGates();
    const [form] = Form.useForm();
    const [herdarOpen, setHerdarOpen] = useState(false);
    const [importarUrlOpen, setImportarUrlOpen] = useState(false);
    /** Sticky «Salvar» no rodapé mobile — teclado / form longo (TASK-APR-048). */
    useMobilePageActionBarRegistration(isMobileLayout);
    const {
        draftBanner,
        savedHint,
        handleFormValuesChange,
        afterSaveSuccess,
        handleCancelEdits,
    } = useProjetoBriefingFormGuard(form, id, 'escopo', { enabled: canEditar });

    const { data: projetoResponse, isLoading } = useQueryCache<
        Projeto | { projeto?: Projeto; metricas?: unknown }
    >({
        queryKey: queryKeys.projetos.detail(id),
        endpoint: API_ENDPOINTS.projetos.show(id),
        enabled: !!id,
        staleTime: 1 * 60 * 1000,
        gcTime: 5 * 60 * 1000,
    });

    const projeto =
        projetoResponse && typeof projetoResponse === 'object' && 'projeto' in projetoResponse
            ? (projetoResponse as { projeto?: Projeto }).projeto
            : (projetoResponse as Projeto | undefined);

    const updateMutation = useMutationCache({
        endpoint: API_ENDPOINTS.projetos.update(id),
        method: 'PUT',
        invalidateQueries: [queryKeys.projetos.detail(id), queryKeys.projetos.lists()],
        onSuccess: () => {
            message.success('Escopo salvo com sucesso!');
            afterSaveSuccess();
        },
        onError: (error: unknown) => {
            notifyApiError(error, 'Erro ao salvar escopo.', 'escopo');
        },
    });

    const herdarMutation = useMutationCache<EscopoPreviewResponse, { projeto_origem_id: number }>({
        endpoint: API_ENDPOINTS.projetos.escopo.herdar(id),
        method: 'POST',
        onSuccess: (data) => {
            aplicarTextoEscopo(data.termo_escopo ?? '', data.message);
            setHerdarOpen(false);
        },
        onError: (error: unknown) => {
            notifyApiError(error, 'Erro ao herdar escopo.', 'escopo');
        },
    });

    const importarUrlMutation = useMutationCache<EscopoPreviewResponse, { url: string }>({
        endpoint: API_ENDPOINTS.projetos.escopo.importarUrl(id),
        method: 'POST',
        onSuccess: (data) => {
            aplicarTextoEscopo(data.termo_escopo ?? '', data.message);
            setImportarUrlOpen(false);
        },
        onError: (error: unknown) => {
            notifyApiError(error, 'Erro ao importar escopo da URL.', 'escopo');
        },
    });

    /** LOG-026: deps primitivas + skip se igual/dirty — evita React #185 (Maximum update depth). */
    const projetoId = projeto?.id;
    const termoEscopoServer = projeto?.termo_escopo ?? '';
    const premissasServer = projeto?.premissas ?? '';
    const restricoesServer = projeto?.restricoes ?? '';
    useEffect(() => {
        if (projetoId == null) return;
        const touched = form.isFieldsTouched(['termo_escopo', 'premissas', 'restricoes']);
        if (touched) return;
        const atual = String(form.getFieldValue('termo_escopo') ?? '');
        const atualPrem = String(form.getFieldValue('premissas') ?? '');
        const atualRest = String(form.getFieldValue('restricoes') ?? '');
        if (
            atual === termoEscopoServer &&
            atualPrem === premissasServer &&
            atualRest === restricoesServer
        ) {
            return;
        }
        form.setFieldsValue({
            termo_escopo: termoEscopoServer,
            premissas: premissasServer,
            restricoes: restricoesServer,
        });
    }, [projetoId, termoEscopoServer, premissasServer, restricoesServer, form]);

    const aplicarTextoEscopo = (texto: string, toast?: string) => {
        form.setFieldsValue({ termo_escopo: texto });
        handleFormValuesChange();
        message.success(toast || 'Escopo carregado no formulário. Revise e salve.');
    };

    const confirmarSubstituicaoSeNecessario = (onConfirm: () => void) => {
        const atual = String(form.getFieldValue('termo_escopo') ?? '').trim();
        if (!atual) {
            onConfirm();
            return;
        }
        confirmDialog({
            title: 'Substituir escopo atual?',
            content:
                'O texto atual do formulário será substituído pelo conteúdo herdado/importado. Você ainda precisará salvar.',
            okText: 'Substituir',
            cancelText: 'Cancelar',
            onOk: onConfirm,
        });
    };

    const handleSubmit = (values: {
        termo_escopo?: string;
        premissas?: string;
        restricoes?: string;
    }) => {
        updateMutation.mutate({
            termo_escopo: values.termo_escopo?.trim() || null,
            premissas: values.premissas?.trim() || null,
            restricoes: values.restricoes?.trim() || null,
        });
    };

    const escopoVazio =
        !String(projeto?.termo_escopo ?? '').trim() &&
        !String(projeto?.premissas ?? '').trim() &&
        !String(projeto?.restricoes ?? '').trim();

    if (isLoading && !projeto) {
        return (
            <ProjetoLayout projetoId={id} pageTitle="Escopo" pageIcon="list-check" titleSection="Escopo">
                <div style={{ textAlign: 'center', padding: 50 }}>
                    <Spin size="large" />
                </div>
            </ProjetoLayout>
        );
    }

    const tooltipSemEdicao = !canEditar
        ? tooltipSemPermissao('editar o escopo do projeto')
        : undefined;

    return (
        <ProjetoLayout
            projetoId={id}
            pageTitle="Escopo"
            pageIcon="list-check"
            titleSection="Escopo"
            breadcrumbItems={[
                { title: 'PROJETO' },
                { title: projeto?.nome || 'Projeto' },
                { title: 'Escopo' },
            ]}
            headerAction={
                <Space wrap size={8} align="center">
                    <Tooltip title={tooltipSemEdicao ?? 'Herdar escopo de outro projeto Waygest'}>
                        <span style={{ display: 'inline-block' }}>
                            <ButtonHeaderIcon
                                data-testid="projeto-escopo-herdar-btn"
                                icon={<FileDown size={ICON_SIZE_MD} aria-hidden />}
                                title="Herdar de projeto"
                                aria-label="Herdar escopo de outro projeto"
                                disabled={!canEditar}
                                onClick={() => setHerdarOpen(true)}
                                className={btnHeaderStyles.btnHeaderIcon}
                            />
                        </span>
                    </Tooltip>
                    <Tooltip title={tooltipSemEdicao ?? 'Importar rascunho de escopo a partir de uma URL'}>
                        <span style={{ display: 'inline-block' }}>
                            <ButtonHeaderIcon
                                data-testid="projeto-escopo-importar-url-btn"
                                icon={<Link2 size={ICON_SIZE_MD} aria-hidden />}
                                title="Importar por URL"
                                aria-label="Importar escopo por URL"
                                disabled={!canEditar}
                                onClick={() => setImportarUrlOpen(true)}
                                className={btnHeaderStyles.btnHeaderIcon}
                            />
                        </span>
                    </Tooltip>
                </Space>
            }
        >
            {draftBanner}
            {savedHint}

            {escopoVazio ? (
                <ProjetoTipologicoSyncBanner
                    projetoId={id}
                    title="Escopo ainda vazio"
                    domainDescription={TIPOLOGICO_EMPTY_DOMAIN.escopo}
                    data-testid="projeto-escopo-sync-banner"
                />
            ) : null}

            {isMobileLayout ? (
                <EscopoPlanejamentoWizardSaveBridge
                    form={form}
                    canEditar={canEditar}
                    saving={updateMutation.isPending}
                    onPersist={async (values) =>
                        updateMutation.mutateAsync({
                            termo_escopo: values.termo_escopo?.trim() || null,
                            premissas: values.premissas?.trim() || null,
                            restricoes: values.restricoes?.trim() || null,
                        })
                    }
                />
            ) : null}

            <Form
                form={form}
                layout="vertical"
                initialValues={{
                    termo_escopo: projeto?.termo_escopo ?? '',
                    premissas: projeto?.premissas ?? '',
                    restricoes: projeto?.restricoes ?? '',
                }}
                onFinish={handleSubmit}
                onValuesChange={handleFormValuesChange}
            >
                <ContentCard title="Termo de escopo">
                    <div className={styles.escopoTextarea}>
                        <FormTextarea
                            name="termo_escopo"
                            aria-label="Termo de escopo"
                            rules={[
                                {
                                    max: 10000,
                                    message: 'Máximo 10.000 caracteres.',
                                },
                            ]}
                            placeholder={resolveEscopoPlaceholder(projeto?.categoria_projeto?.codigo)}
                            rows={isMobileLayout ? 10 : 16}
                            maxLength={10000}
                            showCount
                        />
                    </div>
                </ContentCard>

                <ContentCard title="Premissas">
                    <div className={styles.escopoTextarea}>
                        <FormTextarea
                            name="premissas"
                            aria-label="Premissas"
                            rules={[
                                {
                                    max: 10000,
                                    message: 'Máximo 10.000 caracteres.',
                                },
                            ]}
                            placeholder="Premissas assumidas para o escopo (ex.: disponibilidade de APIs, prazos do cliente)…"
                            rows={isMobileLayout ? 4 : 6}
                            maxLength={10000}
                            showCount
                            data-testid="projeto-escopo-premissas"
                        />
                    </div>
                </ContentCard>

                <ContentCard title="Restrições">
                    <div className={styles.escopoTextarea}>
                        <FormTextarea
                            name="restricoes"
                            aria-label="Restrições"
                            rules={[
                                {
                                    max: 10000,
                                    message: 'Máximo 10.000 caracteres.',
                                },
                            ]}
                            placeholder="Restrições técnicas, legais ou de negócio que limitam o escopo…"
                            rows={isMobileLayout ? 4 : 6}
                            maxLength={10000}
                            showCount
                            data-testid="projeto-escopo-restricoes"
                        />
                    </div>
                </ContentCard>

                {!isMobileLayout ? (
                    <FormActionsWrapper>
                        <Button
                            type="default"
                            onClick={() =>
                                handleCancelEdits({
                                    termo_escopo: projeto?.termo_escopo ?? '',
                                    premissas: projeto?.premissas ?? '',
                                    restricoes: projeto?.restricoes ?? '',
                                })
                            }
                            disabled={updateMutation.isPending || !form.isFieldsTouched()}
                        >
                            Cancelar
                        </Button>
                        <Tooltip title={tooltipSemEdicao}>
                            <span>
                                <Button
                                    type="primary"
                                    htmlType="submit"
                                    loading={updateMutation.isPending}
                                    disabled={!canEditar}
                                    icon={<Save size={ICON_SIZE_MD} aria-hidden />}
                                    data-testid="projeto-escopo-save"
                                >
                                    Salvar
                                </Button>
                            </span>
                        </Tooltip>
                    </FormActionsWrapper>
                ) : null}
            </Form>

            <ModalHerdarEscopoProjeto
                open={herdarOpen}
                projetoAtualId={id}
                confirmLoading={herdarMutation.isPending}
                onClose={() => setHerdarOpen(false)}
                onConfirm={(projetoOrigemId) => {
                    confirmarSubstituicaoSeNecessario(() => {
                        herdarMutation.mutate({ projeto_origem_id: projetoOrigemId });
                    });
                }}
            />

            <ModalImportarEscopoUrl
                open={importarUrlOpen}
                confirmLoading={importarUrlMutation.isPending}
                onClose={() => setImportarUrlOpen(false)}
                onConfirm={(url) => {
                    confirmarSubstituicaoSeNecessario(() => {
                        importarUrlMutation.mutate({ url });
                    });
                }}
            />
        </ProjetoLayout>
    );
}
