'use client';

import React, { useCallback } from 'react';
import { Alert, Button, Card, Form, Input, Modal, Select, Spin, Tooltip } from 'antd';
import { Link2 } from 'lucide-react';
import { message } from '@/lib/feedback/message';
import { notifyApiError } from '@/lib/feedback/notifyApiError';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import { queryKeys } from '@/lib/cache/queryKeys';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { PermissionGuard } from '@/components/permissions';
import { FormActions } from '@/components/form';
import {
    useWaygestFormModalProps,
    waygestFormModalFooterClassName,
    mergeWaygestFormModalBodyStyles,
} from '@/hooks/useWaygestFormModalProps';
import { mensagemErroGitlabListagem } from '@/features/projetos/utils/gitlabListagemErro';
import { confirmVincularRepositorioGitlab } from '@/features/projetos/utils/confirmGitlabRepositorio';
import type { GitLabConfig, GrupoItem, RepoItem } from './types';

export interface ModalVincularRepositorioGitProps {
    open: boolean;
    projetoId: string;
    isMobileLayout: boolean;
    canEditar: boolean;
    permsLoading: boolean;
    tooltipSemPermissao: (acao: string) => string;
    onClose: () => void;
    onSuccess: () => void;
}

export function ModalVincularRepositorioGit({
    open,
    projetoId,
    isMobileLayout,
    canEditar,
    permsLoading,
    tooltipSemPermissao,
    onClose,
    onSuccess,
}: ModalVincularRepositorioGitProps) {
    const modalProps = useWaygestFormModalProps();
    const [formIntegrar] = Form.useForm();
    const [formUrl] = Form.useForm<{ url: string; branch: string }>();

    const {
        data: gruposData,
        isLoading: loadingGrupos,
        isError: gruposIsError,
        error: gruposError,
        refetch: refetchGrupos,
    } = useQueryCache<{ success: boolean; grupos: GrupoItem[] }>({
        queryKey: queryKeys.projetos.gitlabGrupos(projetoId),
        endpoint: API_ENDPOINTS.projetos.gitlab.grupos,
        enabled: open && !!projetoId,
        retry: 1,
    });

    const searchRepos = Form.useWatch('search', formIntegrar);
    const groupId = Form.useWatch('group_id', formIntegrar);

    const {
        data: reposData,
        isLoading: loadingRepos,
        isError: reposIsError,
        error: reposError,
        refetch: refetchRepos,
    } = useQueryCache<{ success: boolean; repositorios: RepoItem[] }>({
        queryKey: queryKeys.projetos.gitlabRepos(projetoId, searchRepos ?? '', groupId ?? ''),
        endpoint: API_ENDPOINTS.projetos.gitlab.repositorios,
        params: { search: searchRepos ?? '', group_id: groupId ?? '' },
        enabled: open && !!projetoId,
        staleTime: 30 * 1000,
        retry: 1,
    });

    const gitlabListagemErro =
        (reposIsError || gruposIsError) &&
        mensagemErroGitlabListagem(reposIsError ? reposError : gruposError);

    const updateMutation = useMutationCache<
        { message?: string; data?: GitLabConfig } | GitLabConfig,
        Record<string, unknown>
    >({
        endpoint: API_ENDPOINTS.projetos.gitlab.update(projetoId),
        method: 'PUT',
        invalidateQueries: [queryKeys.projetos.gitlab(projetoId), queryKeys.projetos.detail(projetoId)],
        onSuccess: (response) => {
            const payload =
                response && typeof response === 'object' && 'data' in response && response.data
                    ? response.data
                    : (response as GitLabConfig | undefined);
            const configurado = Boolean(
                payload?.configurado ||
                    (payload?.gitlab_project_id != null && String(payload.gitlab_project_id).trim() !== ''),
            );
            if (!configurado) {
                message.error(
                    'A API aceitou o pedido, mas o repositório não ficou vinculado (faltou o ID GitLab). Tente vincular pela lista ou reconecte a conta GitLab.',
                );
                return;
            }
            message.success('Repositório vinculado ao projeto com sucesso!');
            formIntegrar.resetFields();
            formUrl.resetFields();
            onSuccess();
            onClose();
        },
        onError: (err: unknown) => {
            notifyApiError(err, 'Erro ao vincular repositório.', 'gitlab');
        },
    });

    const repositorios = reposData?.repositorios ?? [];
    const grupos = gruposData?.grupos ?? [];

    const handleIntegrarPorLista = useCallback(
        (repo: RepoItem) => {
            confirmVincularRepositorioGitlab({
                repositorioRef: repo.full_path,
                url: repo.url,
                branch: repo.default_branch,
                onConfirm: () =>
                    updateMutation.mutate({
                        gitlab_repository_id: repo.id,
                        gitlab_project_id: String(repo.id),
                        gitlab_repository_url: repo.url,
                        gitlab_default_branch: repo.default_branch || 'main',
                    }),
            });
        },
        [updateMutation],
    );

    const handleIntegrarPorUrl = useCallback(
        (values: { url: string; branch: string }) => {
            const branch = values.branch?.trim() || 'main';
            confirmVincularRepositorioGitlab({
                repositorioRef: values.url.trim(),
                branch,
                onConfirm: () =>
                    updateMutation.mutate({
                        gitlab_repository_url: values.url,
                        gitlab_default_branch: branch,
                    }),
            });
        },
        [updateMutation],
    );

    const handleClose = () => {
        formIntegrar.resetFields();
        formUrl.resetFields();
        onClose();
    };

    return (
        <Modal
            {...modalProps}
            open={open}
            title={
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                    <Link2 size={18} aria-hidden />
                    Vincular repositório GitLab
                </span>
            }
            onCancel={handleClose}
            footer={null}
            destroyOnClose
            styles={mergeWaygestFormModalBodyStyles(modalProps)}
        >
            {gitlabListagemErro ? (
                <Alert
                    type="error"
                    showIcon
                    style={{ marginBottom: 16 }}
                    message="Falha na listagem GitLab"
                    description={gitlabListagemErro}
                    action={
                        <Button
                            size="small"
                            onClick={() => {
                                void refetchGrupos();
                                void refetchRepos();
                            }}
                        >
                            Tentar novamente
                        </Button>
                    }
                />
            ) : null}

            <Alert
                message="Vincule um repositório GitLab já existente"
                description="A criação automática de repositório no GitLab ainda não está ativa nesta versão piloto. Selecione na lista ou informe a URL."
                type="info"
                showIcon
                style={{ marginBottom: 16 }}
            />

            <Form form={formIntegrar} layout="vertical" onFinish={() => {}}>
                <Form.Item name="search" label="Buscar repositórios">
                    <Input placeholder="Digite para filtrar por nome" allowClear />
                </Form.Item>
                <Form.Item name="group_id" label="Grupo">
                    <Select
                        placeholder="Selecione um grupo"
                        allowClear
                        loading={loadingGrupos}
                        options={grupos.map((g) => ({ value: g.id, label: g.name }))}
                    />
                </Form.Item>
            </Form>

            {loadingRepos ? (
                <Spin />
            ) : (
                <div style={{ marginTop: 8 }}>
                    <p style={{ marginBottom: 8, fontWeight: 500 }}>Selecione um repositório:</p>
                    <div
                        style={{
                            display: 'flex',
                            flexDirection: 'column',
                            gap: 8,
                            maxHeight: 240,
                            overflow: 'auto',
                        }}
                    >
                        {reposIsError ? (
                            <p style={{ color: '#888' }}>Lista indisponível — use &quot;Tentar novamente&quot; acima.</p>
                        ) : repositorios.length === 0 ? (
                            <p style={{ color: '#888' }}>Nenhum repositório encontrado. Ajuste o grupo ou a busca.</p>
                        ) : (
                            repositorios.map((repo) => (
                                <Card key={repo.id} size="small">
                                    <div
                                        style={{
                                            display: 'flex',
                                            flexDirection: isMobileLayout ? 'column' : 'row',
                                            justifyContent: 'space-between',
                                            alignItems: isMobileLayout ? 'stretch' : 'center',
                                            gap: 8,
                                        }}
                                    >
                                        <div style={{ minWidth: 0 }}>
                                            <strong>{repo.name}</strong>
                                            <div style={{ marginTop: 4, color: '#666', fontSize: 12, wordBreak: 'break-word' }}>
                                                {repo.full_path}
                                            </div>
                                            <small style={{ color: '#888' }}>{repo.default_branch}</small>
                                        </div>
                                        <PermissionGuard
                                            permission="projetos.editar"
                                            module="projetos"
                                            action="update"
                                            fallback={
                                                <Tooltip title={tooltipSemPermissao('vincular o repositório Git ao projeto')}>
                                                    <span>
                                                        <Button type="primary" size="small" block={isMobileLayout} disabled>
                                                            Vincular
                                                        </Button>
                                                    </span>
                                                </Tooltip>
                                            }
                                        >
                                            <Tooltip
                                                title={
                                                    !canEditar && !permsLoading
                                                        ? tooltipSemPermissao('vincular o repositório Git ao projeto')
                                                        : undefined
                                                }
                                            >
                                                <span>
                                                    <Button
                                                        type="primary"
                                                        size="small"
                                                        block={isMobileLayout}
                                                        onClick={() => handleIntegrarPorLista(repo)}
                                                        loading={updateMutation.isPending}
                                                        disabled={!canEditar || permsLoading}
                                                        data-testid={`repositorio-git-vincular-${repo.id}`}
                                                    >
                                                        Vincular
                                                    </Button>
                                                </span>
                                            </Tooltip>
                                        </PermissionGuard>
                                    </div>
                                </Card>
                            ))
                        )}
                    </div>
                </div>
            )}

            <div style={{ marginTop: 20, paddingTop: 16, borderTop: '1px solid #f0f0f0' }} data-testid="repositorio-git-form-url">
                <p style={{ marginBottom: 8, fontWeight: 500 }}>Ou informe a URL do repositório:</p>
                <Form
                    form={formUrl}
                    onFinish={handleIntegrarPorUrl}
                    layout="vertical"
                    initialValues={{ branch: 'main' }}
                >
                    <Form.Item
                        name="url"
                        label="URL do repositório"
                        rules={[{ required: true, message: 'Informe a URL' }]}
                    >
                        <Input
                            placeholder="https://gitlab.com/grupo/projeto"
                            autoComplete="url"
                            inputMode="url"
                            data-testid="repositorio-git-url-input"
                        />
                    </Form.Item>
                    <Form.Item name="branch" label="Branch padrão">
                        <Input placeholder="Branch (ex: main)" data-testid="repositorio-git-branch-input" />
                    </Form.Item>
                    <FormActions sticky={false} className={waygestFormModalFooterClassName}>
                        <Button onClick={handleClose}>Cancelar</Button>
                        <PermissionGuard
                            permission="projetos.editar"
                            module="projetos"
                            action="update"
                            fallback={
                                <Tooltip title={tooltipSemPermissao('vincular o repositório Git ao projeto')}>
                                    <span>
                                        <Button type="primary" disabled data-testid="repositorio-git-salvar-url">
                                            Salvar
                                        </Button>
                                    </span>
                                </Tooltip>
                            }
                        >
                            <Tooltip
                                title={
                                    !canEditar && !permsLoading
                                        ? tooltipSemPermissao('vincular o repositório Git ao projeto')
                                        : undefined
                                }
                            >
                                <span>
                                    <Button
                                        type="primary"
                                        htmlType="submit"
                                        loading={updateMutation.isPending}
                                        disabled={!canEditar || permsLoading}
                                        data-testid="repositorio-git-salvar-url"
                                    >
                                        Salvar
                                    </Button>
                                </span>
                            </Tooltip>
                        </PermissionGuard>
                    </FormActions>
                </Form>
            </div>
        </Modal>
    );
}
