'use client';

/**
 * Catálogo administrativo de agentes técnicos Cursor (subagents).
 * @route /configuracoes/projetos/agentes-tecnicos
 */

import React, { useCallback, useMemo, useState } from 'react';
import {
    Alert,
    Button,
    Form,
    Input,
    Modal,
    Select,
    Space,
    Switch,
    Table,
    Tag,
    Typography,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { Plus, Pencil, Trash2 } from 'lucide-react';
import PageWrapper from '@/components/layouts/PageWrapper';
import PageHeaderPagina from '@/components/layouts/PageHeaderPagina';
import { ListagemEmptyState, ListagemListaError } from '@/components/listings';
import { ICON_SIZE_MD } from '@/components/icons';
import { message } from '@/lib/feedback/message';
import { confirmDialog } from '@/lib/feedback/confirmDialog';
import { useQueryCache } from '@/hooks/useQueryCache';
import { useMutationCache } from '@/hooks/useMutationCache';
import apiClient from '@/lib/api/client';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { queryKeys } from '@/lib/cache/queryKeys';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { usePermissions } from '@/contexts/PermissionsContext';
import {
    PROJETOS_AGENTES_TECNICOS_GERIR,
    PROJETOS_AGENTES_TECNICOS_VISUALIZAR,
} from '@/constants/agentesTecnicosPermissoes';

export type AgenteTecnico = {
    id: number;
    slug: string;
    titulo: string;
    descricao?: string | null;
    conteudo_md?: string;
    model?: string;
    readonly?: boolean;
    path_relativo: string;
    escopo: 'padrao' | 'dominio' | 'custom';
    origem?: string;
    ativo: boolean;
    ordem: number;
};

type FormValues = {
    slug: string;
    titulo: string;
    descricao?: string;
    path_relativo: string;
    escopo: 'padrao' | 'dominio' | 'custom';
    model?: string;
    readonly?: boolean;
    ativo?: boolean;
    ordem?: number;
    conteudo_md?: string;
};

const ESCOPO_LABEL: Record<string, string> = {
    padrao: 'Padrão',
    dominio: 'Domínio',
    custom: 'Custom',
};

export default function AgentesTecnicosListPage() {
    const { hasPermission } = usePermissions();
    const canVer =
        hasPermission(PROJETOS_AGENTES_TECNICOS_VISUALIZAR) ||
        hasPermission(PROJETOS_AGENTES_TECNICOS_GERIR);
    const canGerir = hasPermission(PROJETOS_AGENTES_TECNICOS_GERIR);
    const [busca, setBusca] = useState('');
    const [escopo, setEscopo] = useState<string | undefined>();
    const [modalOpen, setModalOpen] = useState(false);
    const [editing, setEditing] = useState<AgenteTecnico | null>(null);
    const [form] = Form.useForm<FormValues>();

    const filters = useMemo(
        () => ({
            busca: busca || undefined,
            escopo: escopo || undefined,
            paginate: false,
        }),
        [busca, escopo],
    );

    const { data, isLoading, isError, refetch, isFetching } = useQueryCache<AgenteTecnico[]>({
        queryKey: queryKeys.projetos.agentesTecnicos.list(filters),
        queryFn: async () => {
            const res = await apiClient.get(API_ENDPOINTS.projetos.agentesTecnicos.index, {
                params: filters,
            });
            return (res.data?.data ?? res.data ?? []) as AgenteTecnico[];
        },
    });

    const invalidate = useCallback(() => {
        void refetch();
    }, [refetch]);

    const saveMutation = useMutationCache({
        mutationFn: async (values: FormValues) => {
            if (editing) {
                await apiClient.put(API_ENDPOINTS.projetos.agentesTecnicos.update(editing.id), values);
            } else {
                await apiClient.post(API_ENDPOINTS.projetos.agentesTecnicos.store, values);
            }
        },
        onSuccess: () => {
            message.success(editing ? 'Agente atualizado.' : 'Agente criado.');
            setModalOpen(false);
            setEditing(null);
            form.resetFields();
            invalidate();
        },
        onError: (err: unknown) => {
            message.error(getLaravelApiErrorMessage(err) || 'Não foi possível salvar o agente.');
        },
    });

    const deleteMutation = useMutationCache({
        mutationFn: async (id: number) => {
            await apiClient.delete(API_ENDPOINTS.projetos.agentesTecnicos.destroy(id));
        },
        onSuccess: () => {
            message.success('Agente removido.');
            invalidate();
        },
        onError: (err: unknown) => {
            message.error(getLaravelApiErrorMessage(err) || 'Não foi possível remover o agente.');
        },
    });

    const openCreate = () => {
        setEditing(null);
        form.setFieldsValue({
            escopo: 'custom',
            model: 'inherit',
            readonly: false,
            ativo: true,
            ordem: 0,
            conteudo_md: '',
            path_relativo: '',
        });
        setModalOpen(true);
    };

    const openCreateDominio = () => {
        setEditing(null);
        form.setFieldsValue({
            escopo: 'dominio',
            model: 'inherit',
            readonly: true,
            ativo: true,
            ordem: 100,
            slug: '',
            titulo: '',
            descricao:
                'Especialista de domínio do projeto — vocabulário, regras e anti-padrões do contexto (ex.: Judô). Read-only; handoff para PO/implementação.',
            path_relativo: 'domains/',
            conteudo_md: `# Especialista de domínio

**Quando usar:** pedidos que exigem vocabulário, regras ou contexto específico deste domínio.

**Quando não usar:** implementação genérica de API/front sem ambiguidade de domínio.

## Identidade

- Conhece bem o domínio (conceitos, termos, exceções).
- Orienta PO e especialistas técnicos com linguagem alinhada ao negócio.
- Não implementa código — devolve handoff acionável.

## Checklist

- [ ] Glossário mínimo do domínio
- [ ] Regras / restrições relevantes ao pedido
- [ ] Anti-padrões a evitar
- [ ] Handoff para o próximo agente (PO / FE / BE)
`,
        });
        setModalOpen(true);
    };

    const openEdit = (row: AgenteTecnico) => {
        setEditing(row);
        form.setFieldsValue({
            slug: row.slug,
            titulo: row.titulo,
            descricao: row.descricao ?? undefined,
            path_relativo: row.path_relativo,
            escopo: row.escopo,
            model: row.model ?? 'inherit',
            readonly: row.readonly,
            ativo: row.ativo,
            ordem: row.ordem,
            conteudo_md: row.conteudo_md ?? '',
        });
        setModalOpen(true);
    };

    const columns: ColumnsType<AgenteTecnico> = [
        {
            title: 'Título',
            dataIndex: 'titulo',
            key: 'titulo',
            render: (v, row) => (
                <Space direction="vertical" size={0}>
                    <Typography.Text strong>{v}</Typography.Text>
                    <Typography.Text type="secondary" code>
                        {row.slug}
                    </Typography.Text>
                </Space>
            ),
        },
        {
            title: 'Escopo',
            dataIndex: 'escopo',
            key: 'escopo',
            width: 110,
            render: (v: string) => <Tag>{ESCOPO_LABEL[v] ?? v}</Tag>,
        },
        {
            title: 'Arquivo',
            dataIndex: 'path_relativo',
            key: 'path_relativo',
            ellipsis: true,
            render: (v: string) => <Typography.Text code>{v}</Typography.Text>,
        },
        {
            title: 'Ativo',
            dataIndex: 'ativo',
            key: 'ativo',
            width: 90,
            render: (v: boolean) => (v ? <Tag color="success">Sim</Tag> : <Tag>Não</Tag>),
        },
        {
            title: 'Ações',
            key: 'acoes',
            width: 120,
            render: (_, row) => (
                <Space>
                    <Button
                        type="text"
                        icon={<Pencil size={ICON_SIZE_MD} />}
                        disabled={!canGerir}
                        onClick={() => openEdit(row)}
                        aria-label="Editar"
                    />
                    <Button
                        type="text"
                        danger
                        icon={<Trash2 size={ICON_SIZE_MD} />}
                        disabled={!canGerir}
                        onClick={() => {
                            void confirmDialog({
                                title: 'Remover agente técnico?',
                                content: `O agente "${row.titulo}" será removido do catálogo.`,
                                okText: 'Remover',
                                okType: 'danger',
                                onOk: () => deleteMutation.mutateAsync(row.id),
                            });
                        }}
                        aria-label="Remover"
                    />
                </Space>
            ),
        },
    ];

    return (
        <PageWrapper>
            <PageHeaderPagina
                title="Agentes técnicos"
                description="Subagents Cursor (Alfred, FE, BE, domínio…). Catálogo global — não são Cloud Agents."
                extra={
                    <Space wrap>
                        <Button
                            icon={<Plus size={ICON_SIZE_MD} />}
                            disabled={!canGerir}
                            onClick={openCreateDominio}
                        >
                            Agente de domínio
                        </Button>
                        <Button
                            type="primary"
                            icon={<Plus size={ICON_SIZE_MD} />}
                            disabled={!canGerir}
                            onClick={openCreate}
                        >
                            Novo agente
                        </Button>
                    </Space>
                }
            />

            <Space wrap style={{ marginBottom: 16 }}>
                <Input.Search
                    allowClear
                    placeholder="Buscar por título, slug ou path"
                    style={{ width: 280 }}
                    onSearch={setBusca}
                    onChange={(e) => {
                        if (!e.target.value) setBusca('');
                    }}
                />
                <Select
                    allowClear
                    placeholder="Escopo"
                    style={{ width: 160 }}
                    value={escopo}
                    onChange={setEscopo}
                    options={[
                        { value: 'padrao', label: 'Padrão' },
                        { value: 'dominio', label: 'Domínio' },
                        { value: 'custom', label: 'Custom' },
                    ]}
                />
            </Space>

            {isError ? (
                <ListagemListaError onRetry={() => void refetch()} />
            ) : !canVer ? (
                <Alert
                    type="warning"
                    showIcon
                    message="Sem permissão"
                    description="Você não tem permissão para visualizar o catálogo de agentes técnicos."
                />
            ) : (
                <Table<AgenteTecnico>
                    rowKey="id"
                    loading={isLoading || isFetching}
                    columns={columns}
                    dataSource={data ?? []}
                    pagination={{ pageSize: 20, showSizeChanger: true }}
                    locale={{
                        emptyText: (
                            <ListagemEmptyState
                                title="Nenhum agente técnico"
                                description="Rode as migrations do catálogo ou crie o primeiro agente."
                            />
                        ),
                    }}
                />
            )}

            <Modal
                title={editing ? 'Editar agente técnico' : 'Novo agente técnico'}
                open={modalOpen}
                onCancel={() => {
                    setModalOpen(false);
                    setEditing(null);
                }}
                onOk={() => form.submit()}
                confirmLoading={saveMutation.isPending}
                okText="Salvar"
                width={720}
                destroyOnHidden
            >
                <Form
                    form={form}
                    layout="vertical"
                    onFinish={(values) => saveMutation.mutate(values)}
                    onValuesChange={(changed, all) => {
                        if ('slug' in changed && all.escopo === 'dominio' && changed.slug) {
                            const slug = String(changed.slug)
                                .trim()
                                .toLowerCase()
                                .replace(/\s+/g, '-');
                            if (slug && !editing) {
                                form.setFieldValue('path_relativo', `domains/${slug}.md`);
                            }
                        }
                        if ('escopo' in changed && changed.escopo === 'dominio' && all.slug && !editing) {
                            const slug = String(all.slug)
                                .trim()
                                .toLowerCase()
                                .replace(/\s+/g, '-');
                            if (slug) {
                                form.setFieldValue('path_relativo', `domains/${slug}.md`);
                            }
                        }
                    }}
                >
                    <Form.Item
                        name="titulo"
                        label="Título"
                        rules={[{ required: true, message: 'Informe o título.' }]}
                    >
                        <Input />
                    </Form.Item>
                    <Form.Item
                        name="slug"
                        label="Slug (name Cursor)"
                        rules={[{ required: true, message: 'Informe o slug.' }]}
                    >
                        <Input disabled={Boolean(editing)} placeholder="ex.: judo-domain-analyst" />
                    </Form.Item>
                    <Form.Item name="descricao" label="Descrição (roteamento Cursor)">
                        <Input.TextArea rows={2} />
                    </Form.Item>
                    <Form.Item
                        name="path_relativo"
                        label="Path relativo (.cursor/agents/…)"
                        rules={[{ required: true, message: 'Informe o path.' }]}
                    >
                        <Input placeholder="domains/judo-domain-analyst.md" />
                    </Form.Item>
                    <Space wrap size="large">
                        <Form.Item name="escopo" label="Escopo" initialValue="custom">
                            <Select
                                style={{ width: 160 }}
                                options={[
                                    { value: 'padrao', label: 'Padrão' },
                                    { value: 'dominio', label: 'Domínio' },
                                    { value: 'custom', label: 'Custom' },
                                ]}
                            />
                        </Form.Item>
                        <Form.Item name="model" label="Model" initialValue="inherit">
                            <Input style={{ width: 160 }} />
                        </Form.Item>
                        <Form.Item name="ordem" label="Ordem" initialValue={0}>
                            <Input type="number" style={{ width: 100 }} />
                        </Form.Item>
                        <Form.Item name="readonly" label="Readonly" valuePropName="checked">
                            <Switch />
                        </Form.Item>
                        <Form.Item name="ativo" label="Ativo" valuePropName="checked" initialValue>
                            <Switch />
                        </Form.Item>
                    </Space>
                    <Form.Item name="conteudo_md" label="Conteúdo markdown (corpo)">
                        <Input.TextArea rows={12} style={{ fontFamily: 'monospace' }} />
                    </Form.Item>
                </Form>
            </Modal>
        </PageWrapper>
    );
}
