'use client';

/**
 * Repositório Git do projeto (`/projetos/[id]/software/repositorio-git`).
 *
 * Explorador de arquivos (tree view + CodeMirror) quando vinculado;
 * modal para vincular/desconectar repositório GitLab.
 */
import {
    CheckCircle2,
    Circle,
    Code2,
    ExternalLink,
    FolderTree,
    GitBranch,
    Link2,
    Search,
    ShieldCheck,
    Unlink,
} from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import React, { useCallback, useState } from 'react';
import { Alert, Button, Spin, Tooltip, Typography } from 'antd';
import { message } from '@/lib/feedback/message';
import { notifyApiError } from '@/lib/feedback/notifyApiError';
import { confirmDialog } from '@/lib/feedback/confirmDialog';
import { useIsMobile } from '@/hooks/useIsMobile';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import { queryKeys } from '@/lib/cache/queryKeys';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import type { 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 { OperativeRouteHint } from '@/components/layouts/OperativeRouteHint/OperativeRouteHint';
import { EmptyState } from '@/components/empty';
import { withProjetosSoftwareParametrosHub } from '@/lib/routes/projetosParametrosPaths';
import { projetosProjetoCanonical } from '@/lib/routes/projetosProjetoCanonical';
import { ProjetoSoftwareParametrosLinks } from '@/features/projetos/software-parametros';
import { PermissionGuard } from '@/components/permissions';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import type { GitLabConfig } from './types';
import {
    COPY_REPOSITORIO_GIT_NAO_VINCULADO,
    COPY_REPOSITORIO_GIT_VINCULADO,
    normalizeProjetoShowResponse,
} from './repositorioGitHelpers';
import { ModalVincularRepositorioGit } from './ModalVincularRepositorioGit';
import { ModalVisualizarArquivoGit } from './ModalVisualizarArquivoGit';
import { RepositorioGitTreePanel } from './RepositorioGitTreePanel';
import styles from './ProjetoSoftwareRepositorioGitScreen.module.scss';

const { Text, Title } = Typography;

export interface ProjetoSoftwareRepositorioGitScreenProps {
    projetoId: string;
}

function truncateMiddle(value: string, max = 28): string {
    if (value.length <= max) {
        return value;
    }
    const keep = Math.floor((max - 1) / 2);
    return `${value.slice(0, keep)}…${value.slice(-keep)}`;
}

export function ProjetoSoftwareRepositorioGitScreen({
    projetoId: id,
}: ProjetoSoftwareRepositorioGitScreenProps) {
    const { canEditar, permsLoading, tooltipSemPermissao } = useProjetoWriteGates();
    const isMobileLayout = useIsMobile();

    const [modalVincularOpen, setModalVincularOpen] = useState(false);
    const [arquivoAberto, setArquivoAberto] = useState<string | null>(null);

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

    const projeto = normalizeProjetoShowResponse(projetoResponse);

    const {
        data: config,
        isLoading: loadingConfig,
        refetch: refetchConfig,
    } = useQueryCache<GitLabConfig>({
        queryKey: queryKeys.projetos.gitlab(id),
        endpoint: API_ENDPOINTS.projetos.gitlab.config(id),
        enabled: !!id,
        staleTime: 1 * 60 * 1000,
    });

    const disconnectMutation = useMutationCache<GitLabConfig, Record<string, unknown>>({
        endpoint: API_ENDPOINTS.projetos.gitlab.update(id),
        method: 'PUT',
        invalidateQueries: [queryKeys.projetos.gitlab(id), queryKeys.projetos.detail(id)],
        onSuccess: () => {
            message.success('Repositório desconectado do projeto.');
            setArquivoAberto(null);
            void refetchConfig();
            void refetchProjeto();
        },
        onError: (err: unknown) => {
            notifyApiError(err, 'Erro ao desconectar repositório.', 'gitlab');
        },
    });

    const branchRef = config?.gitlab_default_branch || 'main';
    const vinculado = Boolean(
        config?.configurado ||
            (config?.gitlab_project_id != null && String(config.gitlab_project_id).trim() !== ''),
    );
    const repoUrl = config?.gitlab_repository_url?.trim() || '';
    const gitlabId = config?.gitlab_project_id != null ? String(config.gitlab_project_id) : '';

    const handleDesconectar = useCallback(() => {
        confirmDialog({
            title: 'Desconectar repositório?',
            content:
                'O projeto deixará de estar vinculado a este repositório GitLab. Você poderá vincular outro repositório depois.',
            okText: 'Desconectar',
            okType: 'danger',
            onOk: () =>
                disconnectMutation.mutate({
                    gitlab_project_id: null,
                    gitlab_repository_url: null,
                    gitlab_default_branch: null,
                }),
        });
    }, [disconnectMutation]);

    const abrirModalVincular = () => setModalVincularOpen(true);

    const renderDesconectarButton = (block = false) => (
        <PermissionGuard
            permission="projetos.editar"
            module="projetos"
            action="update"
            fallback={
                <Tooltip title={tooltipSemPermissao('desconectar o repositório Git do projeto')}>
                    <span>
                        <Button danger icon={<Unlink size={16} />} disabled block={block}>
                            Desconectar
                        </Button>
                    </span>
                </Tooltip>
            }
        >
            <Tooltip
                title={
                    !canEditar && !permsLoading
                        ? tooltipSemPermissao('desconectar o repositório Git do projeto')
                        : undefined
                }
            >
                <span>
                    <Button
                        danger
                        icon={<Unlink size={16} />}
                        loading={disconnectMutation.isPending}
                        disabled={!canEditar || permsLoading}
                        onClick={handleDesconectar}
                        data-testid="repositorio-git-desconectar"
                        block={block}
                    >
                        Desconectar
                    </Button>
                </span>
            </Tooltip>
        </PermissionGuard>
    );

    const renderVincularButton = (block = false) => (
        <PermissionGuard
            permission="projetos.editar"
            module="projetos"
            action="update"
            fallback={
                <Tooltip title={tooltipSemPermissao('vincular o repositório Git ao projeto')}>
                    <span>
                        <Button type="primary" icon={<Link2 size={16} />} disabled block={block}>
                            Vincular repositório
                        </Button>
                    </span>
                </Tooltip>
            }
        >
            <Tooltip
                title={
                    !canEditar && !permsLoading
                        ? tooltipSemPermissao('vincular o repositório Git ao projeto')
                        : undefined
                }
            >
                <span>
                    <Button
                        type="primary"
                        icon={<Link2 size={16} />}
                        disabled={!canEditar || permsLoading}
                        onClick={abrirModalVincular}
                        data-testid="repositorio-git-abrir-modal-vincular"
                        block={block}
                    >
                        Vincular repositório
                    </Button>
                </span>
            </Tooltip>
        </PermissionGuard>
    );

    const integrationSummaryCard = (
        <ContentCard
            title="Resumo da integração"
            icon={<ShieldCheck size={ICON_SIZE_MD} aria-hidden />}
        >
            <div className={styles.summaryCard}>
                <div className={styles.summaryStatus}>
                    <span className={styles.summaryStatusLabel}>Estado</span>
                    <p className={styles.summaryStatusValue}>Vinculado</p>
                    <p className={styles.summaryStatusHint}>
                        Branch <strong>{branchRef}</strong>
                        {gitlabId ? ` · ID ${gitlabId}` : ''}
                    </p>
                </div>

                <ul className={styles.checklist}>
                    <li className={styles.checklistItem}>
                        <CheckCircle2
                            size={16}
                            className={styles.checklistIconOk}
                            aria-hidden
                        />
                        Repositório associado ao projeto
                    </li>
                    <li className={styles.checklistItem}>
                        <CheckCircle2
                            size={16}
                            className={styles.checklistIconOk}
                            aria-hidden
                        />
                        Branch padrão definida para o explorador
                    </li>
                    <li className={styles.checklistItem}>
                        {repoUrl ? (
                            <CheckCircle2
                                size={16}
                                className={styles.checklistIconOk}
                                aria-hidden
                            />
                        ) : (
                            <Circle
                                size={16}
                                className={styles.checklistIconPending}
                                aria-hidden
                            />
                        )}
                        URL pública/clone disponível
                    </li>
                </ul>

                <div className={styles.summaryActions}>
                    <Button
                        type="primary"
                        icon={<ExternalLink size={16} />}
                        href={repoUrl || undefined}
                        target="_blank"
                        rel="noopener noreferrer"
                        disabled={!repoUrl}
                        block
                    >
                        Abrir no GitLab
                    </Button>
                    {renderDesconectarButton(true)}
                </div>
            </div>
        </ContentCard>
    );

    return (
        <ProjetoLayout
            projetoId={id}
            pageTitle="Repositório GIT"
            pageIcon="git-alt"
            titleSection="Repositório GIT"
            breadcrumbItems={[
                { title: 'PROJETO' },
                { title: projeto?.nome || 'Projeto' },
                { title: 'Repositório GIT' },
            ]}
        >
            <div className={styles.page} data-testid="projeto-software-repositorio-git-screen">
                <OperativeRouteHint
                    type={vinculado ? 'success' : 'warning'}
                    message="Integração Git"
                    description={withProjetosSoftwareParametrosHub(
                        vinculado ? COPY_REPOSITORIO_GIT_VINCULADO : COPY_REPOSITORIO_GIT_NAO_VINCULADO,
                    )}
                >
                    <ProjetoSoftwareParametrosLinks
                        links={[
                            {
                                href: projetosProjetoCanonical.integracoesGitlabConfig(id),
                                label: 'Config GitLab',
                            },
                        ]}
                    />
                </OperativeRouteHint>

                {loadingConfig ? (
                    <div className={styles.loadingWrap}>
                        <Spin size="large" />
                        <Text type="secondary">Carregando integração Git…</Text>
                    </div>
                ) : (
                    <>
                        <section className={styles.hero} aria-labelledby="repositorio-git-hero-title">
                            <div className={styles.heroTop}>
                                <div className={styles.heroCopy}>
                                    <Title
                                        level={4}
                                        id="repositorio-git-hero-title"
                                        className={styles.heroTitle}
                                    >
                                        {vinculado
                                            ? 'Código do projeto no GitLab'
                                            : 'Conecte o repositório Git do projeto'}
                                    </Title>
                                    <p className={styles.heroDescription}>
                                        {vinculado
                                            ? 'Explore pastas e arquivos na branch padrão, abra o código no Waygest e mantenha o vínculo alinhado às pipelines e permissões do GitLab.'
                                            : 'Vincule um repositório GitLab existente para centralizar o código no projeto: navegação de arquivos, visualização de código e handoff claro entre times.'}
                                    </p>
                                </div>
                                {vinculado ? (
                                    <div className={styles.heroActions}>
                                        <Button
                                            icon={<ExternalLink size={16} />}
                                            href={repoUrl || undefined}
                                            target="_blank"
                                            rel="noopener noreferrer"
                                            disabled={!repoUrl}
                                        >
                                            Abrir no GitLab
                                        </Button>
                                        {renderDesconectarButton()}
                                    </div>
                                ) : (
                                    <div className={styles.heroActions}>{renderVincularButton()}</div>
                                )}
                            </div>

                            <MetricsGrid columns={3} mobileCompactCollapsible>
                                <MetricCard
                                    icon={<ShieldCheck size={ICON_SIZE_MD} aria-hidden />}
                                    label="Status"
                                    value={vinculado ? 'Vinculado' : 'Não vinculado'}
                                    subvalue={
                                        vinculado
                                            ? 'Integração ativa com o projeto'
                                            : 'Aguardando vínculo GitLab'
                                    }
                                    variant={vinculado ? 'concluidos' : 'planejamento'}
                                />
                                <MetricCard
                                    icon={<GitBranch size={ICON_SIZE_MD} aria-hidden />}
                                    label="Branch padrão"
                                    value={vinculado ? branchRef : '—'}
                                    subvalue={
                                        vinculado ? 'Referência do explorador' : 'Definida ao vincular'
                                    }
                                    variant={vinculado ? 'ativos' : 'default'}
                                />
                                <MetricCard
                                    icon={<Code2 size={ICON_SIZE_MD} aria-hidden />}
                                    label="Projeto GitLab"
                                    value={
                                        vinculado && gitlabId
                                            ? truncateMiddle(`#${gitlabId}`, 22)
                                            : vinculado
                                              ? 'Sem ID'
                                              : '—'
                                    }
                                    subvalue={
                                        vinculado && repoUrl
                                            ? truncateMiddle(repoUrl.replace(/^https?:\/\//, ''), 36)
                                            : 'ID e URL do repositório'
                                    }
                                    variant={vinculado && gitlabId ? 'projetos' : 'default'}
                                />
                            </MetricsGrid>
                        </section>

                        {vinculado ? (
                            <div className={styles.workspace}>
                                {isMobileLayout ? (
                                    <aside className={styles.sidePanel}>{integrationSummaryCard}</aside>
                                ) : null}

                                <div className={styles.mainPanel}>
                                    <ContentCard
                                        title="Repositório vinculado"
                                        icon={<GitBranch size={ICON_SIZE_MD} aria-hidden />}
                                    >
                                        <div className={styles.repoIdentity}>
                                            <div className={styles.repoUrlBlock}>
                                                <p className={styles.repoUrlLabel}>URL do repositório</p>
                                                <p className={styles.repoUrl}>
                                                    {repoUrl ? (
                                                        <a
                                                            href={repoUrl}
                                                            target="_blank"
                                                            rel="noopener noreferrer"
                                                        >
                                                            {repoUrl}
                                                        </a>
                                                    ) : (
                                                        <Text type="secondary">URL não informada</Text>
                                                    )}
                                                </p>
                                            </div>
                                        </div>
                                    </ContentCard>

                                    <ContentCard
                                        className={styles.explorerCard}
                                        title="Explorador de arquivos"
                                        icon={<FolderTree size={ICON_SIZE_MD} aria-hidden />}
                                        flexColumn
                                    >
                                        <p className={styles.explorerHint}>
                                            Navegue pelas pastas da branch <strong>{branchRef}</strong> e
                                            clique em um arquivo para visualizar o código.
                                        </p>
                                        <RepositorioGitTreePanel
                                            projetoId={id}
                                            branchRef={branchRef}
                                            onOpenFile={setArquivoAberto}
                                        />
                                    </ContentCard>
                                </div>

                                {!isMobileLayout ? (
                                    <aside className={styles.sidePanel}>{integrationSummaryCard}</aside>
                                ) : null}
                            </div>
                        ) : (
                            <div className={styles.workspaceSolo}>
                                <ContentCard
                                    title="Começar a integração"
                                    icon={<Link2 size={ICON_SIZE_MD} aria-hidden />}
                                >
                                    <div className={styles.emptyPanel}>
                                        <EmptyState
                                            icon={
                                                <GitBranch
                                                    size={40}
                                                    className={styles.emptyIcon}
                                                    aria-hidden
                                                />
                                            }
                                            title="Nenhum repositório vinculado"
                                            description="Conecte um repositório GitLab existente para explorar pastas, arquivos e visualizar o código do projeto neste workspace."
                                            action={renderVincularButton()}
                                        />

                                        <div className={styles.emptyBenefits}>
                                            <p className={styles.emptyBenefitsTitle}>
                                                O que você ganha ao vincular
                                            </p>
                                            <ul className={styles.emptyBenefitsList}>
                                                <li className={styles.emptyBenefitItem}>
                                                    <FolderTree
                                                        size={16}
                                                        className={styles.emptyBenefitIcon}
                                                        aria-hidden
                                                    />
                                                    Árvore de pastas e arquivos na branch padrão
                                                </li>
                                                <li className={styles.emptyBenefitItem}>
                                                    <Code2
                                                        size={16}
                                                        className={styles.emptyBenefitIcon}
                                                        aria-hidden
                                                    />
                                                    Visualização de código sem sair do Waygest
                                                </li>
                                                <li className={styles.emptyBenefitItem}>
                                                    <Search
                                                        size={16}
                                                        className={styles.emptyBenefitIcon}
                                                        aria-hidden
                                                    />
                                                    Busca rápida no explorador do repositório
                                                </li>
                                                <li className={styles.emptyBenefitItem}>
                                                    <ShieldCheck
                                                        size={16}
                                                        className={styles.emptyBenefitIcon}
                                                        aria-hidden
                                                    />
                                                    Handoff claro entre projeto, Git e pipelines
                                                </li>
                                            </ul>
                                        </div>

                                        <Alert
                                            type="info"
                                            showIcon
                                            message="Criação remota indisponível no piloto"
                                            description="Crie o repositório manualmente no GitLab e vincule-o ao projeto pelo botão acima."
                                        />
                                    </div>
                                </ContentCard>
                            </div>
                        )}
                    </>
                )}
            </div>

            <ModalVincularRepositorioGit
                open={modalVincularOpen}
                projetoId={id}
                isMobileLayout={isMobileLayout}
                canEditar={canEditar}
                permsLoading={permsLoading}
                tooltipSemPermissao={tooltipSemPermissao}
                onClose={() => setModalVincularOpen(false)}
                onSuccess={() => {
                    void refetchConfig();
                    void refetchProjeto();
                }}
            />

            <ModalVisualizarArquivoGit
                open={!!arquivoAberto}
                projetoId={id}
                filePath={arquivoAberto}
                branchRef={branchRef}
                onClose={() => setArquivoAberto(null)}
            />
        </ProjetoLayout>
    );
}
