'use client';

/**
 * Hospedagem do projeto (`/projetos/[id]/software/hospedagem`).
 * Configuração de provedor, FTP e pasta de publicação com resumo lateral.
 */

import {
    AlertTriangle,
    Cloud,
    FolderOpen,
    HardDrive,
    Save,
    Server,
    ShieldCheck,
} from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import React, { useCallback, useEffect, useMemo } from 'react';
import { useParams } from 'next/navigation';
import { Form, Button, Input, Spin, Tooltip, Typography } from 'antd';
import { message } from '@/lib/feedback/message';
import { notifyApiError } from '@/lib/feedback/notifyApiError';
import { FormInput, FormTextarea, FormRadio, FormNumber } from '@/components/form';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
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 MetricsGrid from '@/components/layouts/MetricsGrid';
import MetricCard from '@/components/layouts/MetricCard';
import { PermissionGuard } from '@/components/permissions';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import { routeProjetoId } from '@/features/projetos/feira-list';
import styles from './projetoSoftwareHospedagemScreen.module.scss';

const { Text } = Typography;

export interface ProjetoHospedagemData {
    usar_hospedagem_devway: boolean;
    ftp_host?: string;
    ftp_porta?: number;
    ftp_usuario?: string;
    ftp_senha?: string;
    pasta_publicacao?: string;
    observacoes?: string;
}

const defaultValues: ProjetoHospedagemData = {
    usar_hospedagem_devway: true,
    ftp_host: '',
    ftp_porta: 21,
    ftp_usuario: '',
    ftp_senha: '',
    pasta_publicacao: '',
    observacoes: '',
};

function hospedagemToFormValues(data: ProjetoHospedagemData) {
    return {
        usar_hospedagem_devway: data.usar_hospedagem_devway ? 'sim' : 'nao',
        ftp_host: data.ftp_host ?? '',
        ftp_porta: data.ftp_porta ?? 21,
        ftp_usuario: data.ftp_usuario ?? '',
        ftp_senha: data.ftp_senha ?? '',
        pasta_publicacao: data.pasta_publicacao ?? '',
        observacoes: data.observacoes ?? '',
    };
}

export function ProjetoSoftwareHospedagemScreen() {
    const params = useParams();
    const id = routeProjetoId(params);
    const { canEditar, permsLoading, tooltipSemPermissao } = useProjetoWriteGates();
    const [form] = Form.useForm();

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

    const { data: hospedagemData, isLoading: isLoadingHospedagem } = useQueryCache<ProjetoHospedagemData>({
        queryKey: queryKeys.projetos.infraestrutura(id),
        endpoint: API_ENDPOINTS.projetos.infraestrutura(id),
        enabled: !!id,
        staleTime: 2 * 60 * 1000,
        gcTime: 5 * 60 * 1000,
    });

    const mutation = useMutationCache({
        endpoint: API_ENDPOINTS.projetos.infraestrutura(id),
        method: 'PUT',
        invalidateQueries: [[...queryKeys.projetos.detail(id), 'infraestrutura']],
    });

    const usarDevway = Form.useWatch('usar_hospedagem_devway', form);
    const ftpHostWatch = Form.useWatch('ftp_host', form);
    const ftpUsuarioWatch = Form.useWatch('ftp_usuario', form);
    const ftpPortaWatch = Form.useWatch('ftp_porta', form);
    const pastaWatch = Form.useWatch('pasta_publicacao', form);

    const exibirFtp = usarDevway === false || usarDevway === 'nao';
    const usarWaygest = usarDevway === 'sim' || usarDevway === true;
    const ftpHostOk = Boolean(String(ftpHostWatch ?? '').trim());
    const ftpUsuarioOk = Boolean(String(ftpUsuarioWatch ?? '').trim());
    const ftpOk = !exibirFtp || (ftpHostOk && ftpUsuarioOk);
    const pastaPreenchida = Boolean(String(pastaWatch ?? '').trim());

    const applyFormValues = useCallback(
        (data: ProjetoHospedagemData) => {
            form.setFieldsValue(hospedagemToFormValues(data));
        },
        [form],
    );

    useEffect(() => {
        if (hospedagemData) {
            applyFormValues(hospedagemData);
        } else if (!isLoadingHospedagem && !hospedagemData) {
            applyFormValues(defaultValues);
        }
    }, [hospedagemData, isLoadingHospedagem, applyFormValues]);

    const checklist = useMemo(() => {
        const items = [
            {
                label: 'Provedor de hospedagem definido',
                done: usarDevway === 'sim' || usarDevway === 'nao',
                warn: false,
            },
            {
                label: 'Pasta de publicação informada',
                done: pastaPreenchida,
                warn: false,
            },
        ];

        if (exibirFtp) {
            items.push({
                label: 'Credenciais FTP/SFTP preenchidas',
                done: ftpOk,
                warn: !ftpOk && ftpHostOk,
            });
        }

        return items;
    }, [usarDevway, pastaPreenchida, exibirFtp, ftpOk, ftpHostOk]);

    const checklistConcluido = checklist.filter((item) => item.done).length;

    const handleSubmit = (values: Record<string, unknown>) => {
        const payload: ProjetoHospedagemData = {
            usar_hospedagem_devway: values.usar_hospedagem_devway === 'sim',
            pasta_publicacao: (values.pasta_publicacao as string)?.trim() || undefined,
            observacoes: (values.observacoes as string)?.trim() || undefined,
        };

        if (payload.usar_hospedagem_devway === false) {
            payload.ftp_host = (values.ftp_host as string)?.trim() || undefined;
            payload.ftp_porta = values.ftp_porta != null ? Number(values.ftp_porta) : 21;
            payload.ftp_usuario = (values.ftp_usuario as string)?.trim() || undefined;
            payload.ftp_senha = (values.ftp_senha as string) || undefined;
        }

        mutation.mutate(payload, {
            onSuccess: () => {
                message.success('Configurações de hospedagem guardadas com sucesso.');
            },
            onError: (error) => {
                notifyApiError(error, 'Erro ao salvar hospedagem. Tente novamente.', 'infra');
            },
        });
    };

    const handleReset = () => {
        if (hospedagemData) {
            applyFormValues(hospedagemData);
        } else {
            applyFormValues(defaultValues);
        }
    };

    const isLoading = isLoadingProjeto || isLoadingHospedagem;

    if (isLoading && !projeto && !hospedagemData) {
        return (
            <ProjetoLayout projetoId={id} pageTitle="Hospedagem" pageIcon="cloud" titleSection="Hospedagem">
                <div className={styles.loadingWrap}>
                    <Spin size="large" />
                    <Text type="secondary">Carregando configurações…</Text>
                </div>
            </ProjetoLayout>
        );
    }

    const hospedagemLabel = usarWaygest ? 'Waygest' : exibirFtp ? 'Externa' : 'Pendente';
    const ftpLabel = !exibirFtp ? 'Via Waygest' : ftpOk ? 'Completo' : ftpHostOk ? 'Incompleto' : 'Pendente';

    return (
        <ProjetoLayout
            projetoId={id}
            pageTitle="Hospedagem"
            pageIcon="cloud"
            titleSection="Hospedagem"
            breadcrumbItems={[
                { title: 'PROJETO' },
                { title: projeto?.nome || 'Projeto' },
                { title: 'Hospedagem' },
            ]}
        >
            <div className={styles.page} data-testid="projeto-software-hospedagem-screen">
                <section className={styles.hero} aria-labelledby="hospedagem-hero-title">
                    <div className={styles.heroCopy}>
                        <Typography.Title level={4} id="hospedagem-hero-title" className={styles.heroTitle}>
                            Configure a hospedagem do projeto
                        </Typography.Title>
                        <p className={styles.heroDescription}>
                            Defina onde o site ou aplicação será publicado, credenciais de deploy e pasta de
                            destino. Informação clara reduz fricção em incidentes e handoffs entre equipes.
                        </p>
                    </div>
                    <MetricsGrid columns={3} mobileCompactCollapsible>
                        <MetricCard
                            icon={<Cloud size={ICON_SIZE_MD} aria-hidden />}
                            label="Provedor"
                            value={hospedagemLabel}
                            subvalue={
                                usarWaygest
                                    ? 'Infraestrutura Waygest'
                                    : exibirFtp
                                      ? 'Servidor do cliente ou terceiro'
                                      : 'Selecione abaixo'
                            }
                            variant={usarWaygest ? 'ativos' : exibirFtp ? 'planejamento' : 'default'}
                        />
                        <MetricCard
                            icon={<Server size={ICON_SIZE_MD} aria-hidden />}
                            label="Acesso FTP"
                            value={ftpLabel}
                            subvalue={
                                exibirFtp && ftpPortaWatch
                                    ? `Porta ${ftpPortaWatch}`
                                    : 'Deploy e publicação'
                            }
                            variant={ftpOk ? 'concluidos' : exibirFtp ? 'emAndamento' : 'sprints'}
                        />
                        <MetricCard
                            icon={<FolderOpen size={ICON_SIZE_MD} aria-hidden />}
                            label="Pasta de deploy"
                            value={pastaPreenchida ? String(pastaWatch).trim() : 'Pendente'}
                            subvalue={pastaPreenchida ? 'Caminho definido' : 'Ex.: public_html'}
                            variant={pastaPreenchida ? 'projetos' : 'planejamento'}
                        />
                    </MetricsGrid>
                </section>

                <Form
                    form={form}
                    layout="vertical"
                    onFinish={handleSubmit}
                    initialValues={hospedagemToFormValues(defaultValues)}
                >
                    <div className={styles.workspace}>
                        <div className={styles.formPanel}>
                            <ContentCard
                                title="Provedor de hospedagem"
                                icon={<Cloud size={ICON_SIZE_MD} aria-hidden />}
                            >
                                <FormRadio
                                    name="usar_hospedagem_devway"
                                    label="O cliente usará o servidor de hospedagem da Waygest?"
                                    required
                                    options={[
                                        { label: 'Sim — infraestrutura Waygest', value: 'sim' },
                                        { label: 'Não — servidor externo (FTP/SFTP)', value: 'nao' },
                                    ]}
                                />
                            </ContentCard>

                            {exibirFtp ? (
                                <ContentCard
                                    title="Acesso ao servidor externo"
                                    icon={<HardDrive size={ICON_SIZE_MD} aria-hidden />}
                                >
                                    <div className={styles.ftpPanel}>
                                        <p className={styles.ftpPanelTitle}>Credenciais FTP / SFTP</p>
                                        <FormInput
                                            name="ftp_host"
                                            label="Host"
                                            placeholder="Ex.: ftp.exemplo.com ou 192.168.1.1"
                                            required
                                            help="Endereço do servidor de hospedagem"
                                        />
                                        <FormNumber
                                            name="ftp_porta"
                                            label="Porta"
                                            min={1}
                                            max={65535}
                                            precision={0}
                                            placeholder="21"
                                            rules={[{ required: true, message: 'Informe a porta.' }]}
                                            help="Geralmente 21 (FTP) ou 22 (SFTP)"
                                        />
                                        <FormInput
                                            name="ftp_usuario"
                                            label="Usuário"
                                            placeholder="Usuário de acesso ao servidor"
                                            required
                                        />
                                        <Form.Item
                                            name="ftp_senha"
                                            label="Senha"
                                            help="Armazenada de forma segura. Deixe em branco para não alterar."
                                        >
                                            <Input.Password
                                                placeholder="Senha de acesso"
                                                autoComplete="new-password"
                                            />
                                        </Form.Item>
                                    </div>
                                </ContentCard>
                            ) : null}

                            <ContentCard
                                title="Publicação e notas"
                                icon={<FolderOpen size={ICON_SIZE_MD} aria-hidden />}
                            >
                                <FormInput
                                    name="pasta_publicacao"
                                    label="Pasta no servidor para publicação"
                                    placeholder="Ex.: public_html, www, htdocs ou /var/www/site"
                                    help="Caminho onde o projeto deve ser publicado"
                                />

                                <FormTextarea
                                    name="observacoes"
                                    label="Observações"
                                    rows={4}
                                    placeholder="Ambiente de staging, SSH, painel de controle, contatos de suporte do hosting, etc."
                                />
                            </ContentCard>
                        </div>

                        <aside className={styles.summaryPanel} aria-label="Resumo de hospedagem">
                            <ContentCard title="Resumo e checklist" flexColumn loading={isLoadingHospedagem}>
                                <div className={styles.summaryCard}>
                                    <div className={styles.summaryStatus}>
                                        <span className={styles.summaryStatusLabel}>Estado do formulário</span>
                                        <p className={styles.summaryStatusValue}>
                                            {checklistConcluido}/{checklist.length} itens concluídos
                                        </p>
                                    </div>

                                    <div className={styles.summaryStatus}>
                                        <span className={styles.summaryStatusLabel}>Ambiente</span>
                                        <p className={styles.summaryStatusValue}>{hospedagemLabel}</p>
                                    </div>

                                    {exibirFtp && ftpHostWatch ? (
                                        <div className={styles.summaryStatus}>
                                            <span className={styles.summaryStatusLabel}>Servidor</span>
                                            <p className={styles.summaryStatusValue}>
                                                {String(ftpHostWatch).trim()}
                                                {ftpPortaWatch ? `:${ftpPortaWatch}` : ''}
                                            </p>
                                        </div>
                                    ) : null}

                                    {exibirFtp && !ftpOk ? (
                                        <p className={styles.summaryHint}>
                                            <AlertTriangle
                                                size={14}
                                                style={{ marginRight: 6, verticalAlign: -2 }}
                                                aria-hidden
                                            />
                                            Preencha host e usuário para deploy em servidor externo.
                                        </p>
                                    ) : null}

                                    <div>
                                        <span className={styles.summaryStatusLabel}>Checklist de deploy</span>
                                        <ul className={styles.checklist}>
                                            {checklist.map((item) => (
                                                <li key={item.label} className={styles.checklistItem}>
                                                    <ShieldCheck
                                                        size={16}
                                                        aria-hidden
                                                        className={
                                                            item.done
                                                                ? styles.checklistIconOk
                                                                : item.warn
                                                                  ? styles.checklistIconWarn
                                                                  : styles.checklistIconPending
                                                        }
                                                    />
                                                    <span>{item.label}</span>
                                                </li>
                                            ))}
                                        </ul>
                                    </div>

                                    <div className={styles.summaryActions}>
                                        <PermissionGuard
                                            permission="projetos.editar"
                                            module="projetos"
                                            action="update"
                                            fallback={
                                                <Tooltip
                                                    title={tooltipSemPermissao(
                                                        'editar a hospedagem do projeto',
                                                    )}
                                                >
                                                    <span style={{ display: 'block', width: '100%' }}>
                                                        <Button
                                                            type="primary"
                                                            block
                                                            size="large"
                                                            disabled
                                                            icon={
                                                                <Save
                                                                    size={ICON_SIZE_MD}
                                                                    aria-hidden
                                                                />
                                                            }
                                                            data-testid="projeto-hospedagem-save"
                                                        >
                                                            Salvar hospedagem
                                                        </Button>
                                                    </span>
                                                </Tooltip>
                                            }
                                        >
                                            <Tooltip
                                                title={
                                                    !canEditar && !permsLoading
                                                        ? tooltipSemPermissao(
                                                              'editar a hospedagem do projeto',
                                                          )
                                                        : undefined
                                                }
                                            >
                                                <span style={{ display: 'block', width: '100%' }}>
                                                    <Button
                                                        type="primary"
                                                        block
                                                        size="large"
                                                        htmlType="submit"
                                                        loading={mutation.isPending}
                                                        disabled={!canEditar || permsLoading}
                                                        icon={
                                                            <Save
                                                                size={ICON_SIZE_MD}
                                                                aria-hidden
                                                            />
                                                        }
                                                        data-testid="projeto-hospedagem-save"
                                                    >
                                                        Salvar hospedagem
                                                    </Button>
                                                </span>
                                            </Tooltip>
                                        </PermissionGuard>
                                        <Button
                                            block
                                            size="large"
                                            onClick={handleReset}
                                            disabled={mutation.isPending}
                                        >
                                            Restaurar valores
                                        </Button>
                                    </div>
                                </div>
                            </ContentCard>
                        </aside>
                    </div>
                </Form>
            </div>
        </ProjetoLayout>
    );
}
