'use client';

/**
 * Painel S2.3 do passo Deploy — config manual + Validar deploy (HTTPS /health).
 */

import { useCallback, useState } from 'react';
import Link from 'next/link';
import { Alert, Button, Space, Typography } from 'antd';
import { Download, ExternalLink, ShieldCheck } from 'lucide-react';

import { ICON_SIZE_SM } from '@/components/icons';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import apiClient from '@/lib/api/client';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { message } from '@/lib/feedback/message';

import { downloadConectarArtefacto } from './downloadConectarArtefacto';
import type { ConectarPassoDto } from './types';

const { Text, Paragraph } = Typography;

const CI_TEMPLATES = [
    { id: 'gitlab-ci-php', label: 'GitLab CI (PHP)', file: '.gitlab-ci.yml' },
    { id: 'gitlab-ci-node', label: 'GitLab CI (Node)', file: '.gitlab-ci.yml' },
    { id: 'github-actions-node', label: 'GitHub Actions (Node)', file: 'waygest-ci.yml' },
] as const;

type ValidarDeployResponse = {
    data: {
        ok: boolean;
        status_http: number | null;
        codigo: string | null;
        mensagem: string | null;
        validado_em: string;
        url_validada?: string | null;
    };
};

type Props = {
    projetoId: string;
    passo: ConectarPassoDto;
    onAtualizarStatus: () => Promise<unknown>;
};

export function ConectarDeployPassoPanel({ projetoId, passo, onAtualizarStatus }: Props) {
    const [loading, setLoading] = useState(false);
    const [ciBusy, setCiBusy] = useState<string | null>(null);
    const [last, setLast] = useState<ValidarDeployResponse['data'] | null>(null);

    const temDominio = passo.sinais.tem_dominio === true;
    const deployAplicavel = passo.sinais.deploy_aplicavel !== false;
    const deployNaMotivo =
        typeof passo.sinais.deploy_na_motivo === 'string' ? passo.sinais.deploy_na_motivo : null;
    const hospedagem =
        typeof passo.links.hospedagem === 'string'
            ? passo.links.hospedagem
            : `/projetos/${projetoId}/software/hospedagem`;

    const validar = useCallback(async () => {
        setLoading(true);
        setLast(null);
        try {
            const res = await apiClient.post<ValidarDeployResponse>(
                API_ENDPOINTS.projetos.conectarValidarDeploy(projetoId),
                {},
            );
            const data = res.data?.data;
            setLast(data ?? null);
            await onAtualizarStatus();
            if (data?.ok) {
                message.success('Deploy alcançável — passo pode ser concluído.');
            } else {
                message.error(data?.mensagem ?? 'Validação de deploy falhou.');
            }
        } catch (e: unknown) {
            message.error(
                getLaravelApiErrorMessage(e, 'Não foi possível validar o deploy.'),
            );
        } finally {
            setLoading(false);
        }
    }, [projetoId, onAtualizarStatus]);

    const baixarCi = useCallback(
        async (templateId: string, fallback: string) => {
            setCiBusy(templateId);
            try {
                await downloadConectarArtefacto(
                    API_ENDPOINTS.projetos.conectarCiTemplate(projetoId, templateId),
                    fallback,
                );
                message.success('Template baixado. Coloque no repositório do projeto.');
            } catch (e: unknown) {
                message.error(e instanceof Error ? e.message : 'Falha ao baixar template.');
            } finally {
                setCiBusy(null);
            }
        },
        [projetoId],
    );

    return (
        <Space direction="vertical" size="middle" style={{ width: '100%' }}>
            {!deployAplicavel ? (
                <Alert
                    type="warning"
                    showIcon
                    message="Deploy público geralmente N/A neste tipo"
                    description={
                        <Paragraph style={{ marginBottom: 0 }}>
                            {deployNaMotivo ??
                                'Para este tipo de projeto o passo Deploy é opcional. Use «Pular por agora» se não houver URL HTTPS de produção.'}
                        </Paragraph>
                    }
                />
            ) : (
                <Alert
                    type="info"
                    showIcon
                    message="Deploy manual + alcance HTTPS"
                    description={
                        <Paragraph style={{ marginBottom: 0 }}>
                            Cadastre o domínio em Hospedagem. O botão confere se{' '}
                            <Text code>https://seu-dominio/health</Text> responde 2xx — não prova
                            CI, FTP nem login da aplicação.
                        </Paragraph>
                    }
                />
            )}

            {deployAplicavel && !temDominio ? (
                <Alert
                    type="warning"
                    showIcon
                    message="Cadastre um domínio HTTPS"
                    description={
                        <Space direction="vertical" size="small">
                            <Text>
                                Sem domínio no projeto não há URL pública para validar. FTP ou
                                hospedagem Devway sozinhos não bastam. Se ainda não houver URL,
                                use «Pular por agora».
                            </Text>
                            <Link href={hospedagem}>Abrir hospedagem</Link>
                        </Space>
                    }
                />
            ) : null}

            <Space wrap>
                <Button
                    type="primary"
                    icon={<ShieldCheck size={ICON_SIZE_SM} />}
                    loading={loading}
                    disabled={!temDominio}
                    onClick={() => void validar()}
                >
                    Validar deploy
                </Button>
                <Button href={hospedagem} icon={<ExternalLink size={ICON_SIZE_SM} />}>
                    Abrir hospedagem
                </Button>
            </Space>

            <div>
                <Text strong>Templates de pipeline (opcional)</Text>
                <Paragraph type="secondary" style={{ marginBottom: 8, marginTop: 4 }}>
                    Baixe um esqueleto GitLab CI / GitHub Actions para o repositório. O deploy
                    automático completo continua fora do Waygest — use Validar deploy para o
                    health HTTPS.
                </Paragraph>
                <Space wrap>
                    {CI_TEMPLATES.map((t) => (
                        <Button
                            key={t.id}
                            size="small"
                            icon={<Download size={ICON_SIZE_SM} />}
                            loading={ciBusy === t.id}
                            onClick={() => void baixarCi(t.id, t.file)}
                        >
                            {t.label}
                        </Button>
                    ))}
                </Space>
            </div>

            {last ? (
                <Alert
                    type={last.ok ? 'success' : 'error'}
                    showIcon
                    message={last.ok ? 'Health alcançável' : last.codigo ?? 'Falha'}
                    description={
                        <Space direction="vertical" size={4}>
                            {last.mensagem ? <Text>{last.mensagem}</Text> : null}
                            {last.url_validada ? (
                                <Text type="secondary">
                                    URL: <Text code>{last.url_validada}</Text>
                                    {last.status_http != null
                                        ? ` · HTTP ${last.status_http}`
                                        : ''}
                                </Text>
                            ) : null}
                            {!last.ok ? <Link href={hospedagem}>Corrigir em hospedagem</Link> : null}
                        </Space>
                    }
                />
            ) : null}

            {passo.sinais.ultima_validacao_ok === true && !last ? (
                <Alert
                    type="success"
                    showIcon
                    message="Última validação OK"
                    description={
                        typeof passo.sinais.ultima_validacao_em === 'string'
                            ? `Em ${passo.sinais.ultima_validacao_em}`
                            : undefined
                    }
                />
            ) : null}
        </Space>
    );
}
