'use client';

/**
 * Lista admin de tokens pessoais Cursor ativos no projeto (ADR-0085 / S4).
 * Metadados apenas — sem hash/plaintext.
 */

import React, { useCallback, useState } from 'react';
import { Alert, Button, Card, Popconfirm, Spin, Table, Typography } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { useQueryClient } from '@tanstack/react-query';
import { message } from '@/lib/feedback/message';
import apiClient from '@/lib/api/client';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { queryKeys } from '@/lib/cache/queryKeys';
import { useQueryCache } from '@/hooks/useQueryCache';
import { usePermissions } from '@/contexts/PermissionsContext';
import { useProjetoWriteGates } from '@/features/projetos/hooks/useProjetoWriteGates';
import {
    formatCursorUserTokenDate,
    type ProjetoCursorUserTokenAdminItem,
} from './projetoCursorUserToken';

export type ProjetoCursorUserTokensAdminSectionProps = {
    projetoId: string;
};

export function ProjetoCursorUserTokensAdminSection({
    projetoId,
}: ProjetoCursorUserTokensAdminSectionProps) {
    const queryClient = useQueryClient();
    const { canEditar, permsLoading } = useProjetoWriteGates();
    const { hasPermission, loading: globalPermsLoading } = usePermissions();
    const canAdminTokens =
        canEditar || hasPermission('cursor.user-token.admin');
    const gatesLoading = permsLoading || globalPermsLoading;
    const [revokingId, setRevokingId] = useState<number | null>(null);

    const {
        data: envelope,
        isLoading,
        error,
        refetch,
    } = useQueryCache<{ data: ProjetoCursorUserTokenAdminItem[] }>({
        queryKey: queryKeys.projetos.cursorUserTokens(projetoId),
        endpoint: API_ENDPOINTS.projetos.cursorUserToken.index(projetoId),
        enabled: Boolean(projetoId) && canAdminTokens && !gatesLoading,
    });

    const rows = envelope?.data ?? [];
    const statusError = error
        ? getLaravelApiErrorMessage(error, 'Não foi possível listar os tokens pessoais Cursor.')
        : null;

    const handleRevoke = useCallback(
        async (usuarioId: number) => {
            setRevokingId(usuarioId);
            try {
                await apiClient.post(
                    API_ENDPOINTS.projetos.cursorUserToken.revokeUsuario(projetoId, usuarioId),
                );
                message.success('Token pessoal do usuário revogado.');
                await queryClient.invalidateQueries({
                    queryKey: queryKeys.projetos.cursorUserTokens(projetoId),
                });
                await queryClient.invalidateQueries({
                    queryKey: queryKeys.projetos.cursorUserToken(projetoId),
                });
            } catch (e: unknown) {
                message.error(
                    getLaravelApiErrorMessage(e, 'Não foi possível revogar o token do usuário.'),
                );
            } finally {
                setRevokingId(null);
            }
        },
        [projetoId, queryClient],
    );

    if (gatesLoading) {
        return (
            <Card title="Tokens pessoais da equipe" size="small" style={{ marginBottom: 16 }}>
                <div style={{ textAlign: 'center', padding: 24 }}>
                    <Spin />
                </div>
            </Card>
        );
    }

    if (!canAdminTokens) {
        return null;
    }

    const columns: ColumnsType<ProjetoCursorUserTokenAdminItem> = [
        {
            title: 'Usuário',
            key: 'usuario',
            render: (_, r) => r.usuario_nome?.trim() || `ID ${r.usuario_id}`,
        },
        {
            title: 'Prefixo',
            dataIndex: 'token_prefix',
            key: 'token_prefix',
            render: (v: string) => <Typography.Text code>{v}</Typography.Text>,
        },
        {
            title: 'Dispositivo',
            dataIndex: 'device_label',
            key: 'device_label',
            render: (v: string | null) => v?.trim() || '—',
        },
        {
            title: 'Último uso',
            dataIndex: 'last_used_at',
            key: 'last_used_at',
            render: (v: string | null) => formatCursorUserTokenDate(v),
        },
        {
            title: 'Ações',
            key: 'acoes',
            width: 120,
            render: (_, r) => (
                <Popconfirm
                    title={`Revogar token de ${r.usuario_nome ?? r.usuario_id}?`}
                    description="O pack desse usuário deixa de autenticar até ele gerar outro."
                    okText="Revogar"
                    cancelText="Cancelar"
                    okButtonProps={{ danger: true, loading: revokingId === r.usuario_id }}
                    onConfirm={() => void handleRevoke(r.usuario_id)}
                >
                    <Button
                        danger
                        size="small"
                        loading={revokingId === r.usuario_id}
                        data-testid={`cursor-user-token-admin-revoke-${r.usuario_id}`}
                    >
                        Revogar
                    </Button>
                </Popconfirm>
            ),
        },
    ];

    return (
        <Card
            title="Tokens pessoais da equipe"
            size="small"
            style={{ marginBottom: 16 }}
            data-testid="cursor-user-tokens-admin"
            extra={
                <Button size="small" onClick={() => void refetch()}>
                    Atualizar
                </Button>
            }
        >
            <Alert
                type="info"
                showIcon
                style={{ marginBottom: 12 }}
                message="Somente metadados"
                description="Prefixo e último uso — nunca o valor completo do token."
            />

            {statusError ? (
                <Alert type="error" showIcon style={{ marginBottom: 12 }} message={statusError} />
            ) : null}

            {isLoading && rows.length === 0 ? (
                <div style={{ textAlign: 'center', padding: 16 }}>
                    <Spin size="small" />
                </div>
            ) : (
                <Table<ProjetoCursorUserTokenAdminItem>
                    size="small"
                    rowKey="usuario_id"
                    columns={columns}
                    dataSource={rows}
                    pagination={false}
                    locale={{ emptyText: 'Nenhum token pessoal ativo neste projeto.' }}
                    scroll={{ x: true }}
                />
            )}
        </Card>
    );
}
