/**
 * Arcadia Suite - Generator Agent
 * 
 * Agente responsável por gerar código a partir de especificações.
 * Lê arquivos existentes para manter consistência.
 * 
 * @author Arcadia Development Team
 * @version 2.0.0
 */

import { BaseBlackboardAgent, type AgentConfig } from "../BaseBlackboardAgent";
import { blackboardService } from "../service";
import { type BlackboardTask } from "@shared/schema";
import { toolManager } from "../../autonomous/tools";

const SYSTEM_PROMPT = `Você é o Agente Gerador de Código do Arcadia Suite.

## Seu Papel
Você gera código TypeScript/React de alta qualidade baseado em especificações técnicas.
Você pode ler arquivos existentes para manter consistência de estilo.

## Stack do Arcadia Suite
- Backend: Node.js, Express, TypeScript
- Frontend: React 18, TypeScript, Tailwind CSS, shadcn/ui
- Banco: PostgreSQL com Drizzle ORM
- Autenticação: Passport.js com sessões
- Estado: TanStack Query (React Query)

## Padrões de Código
1. Sempre use TypeScript com tipos estritos
2. Use componentes funcionais com hooks
3. Siga o padrão existente de rotas Express
4. Use Drizzle ORM para queries
5. Use shadcn/ui para componentes de UI
6. Adicione data-testid em elementos interativos

## Formato de Saída
Para cada arquivo, retorne JSON:
{
  "files": [
    {
      "path": "caminho/completo/arquivo.ts",
      "content": "código completo do arquivo",
      "type": "schema|route|component|hook|util",
      "action": "create|modify"
    }
  ]
}`;

export class GeneratorAgent extends BaseBlackboardAgent {
  constructor() {
    const config: AgentConfig = {
      name: "generator",
      displayName: "Agente Gerador de Código",
      description: "Gera código TypeScript/React a partir de especificações",
      systemPrompt: SYSTEM_PROMPT,
      capabilities: [
        "Geração de schemas Drizzle",
        "Criação de rotas Express",
        "Componentes React/TypeScript",
        "Leitura de código existente",
        "Manutenção de consistência"
      ],
      pollInterval: 2000
    };
    super(config);
  }

  canHandle(task: BlackboardTask): boolean {
    const context = task.context as any;
    return context?.phase === "codegen" || task.assignedAgent === "generator";
  }

  async process(task: BlackboardTask): Promise<void> {
    await this.log(task.id, "thinking", "Buscando especificação e contexto...");

    const specArtifact = await blackboardService.getLatestArtifact(task.id, "spec");
    const contextArtifact = await blackboardService.getLatestArtifact(task.id, "doc");

    if (!specArtifact) {
      await blackboardService.failTask(task.id, "generator", "Especificação não encontrada");
      return;
    }

    let spec: any;
    try {
      spec = JSON.parse(specArtifact.content || "{}");
    } catch {
      spec = { raw: specArtifact.content };
    }

    await this.log(task.id, "reading", "Lendo arquivos de referência...");

    let schemaRef = "";
    const schemaResult = await toolManager.execute("read_file", { path: "shared/schema.ts", startLine: 1, endLine: 100 });
    if (schemaResult.success) {
      schemaRef = `\nREFERÊNCIA - shared/schema.ts (primeiras 100 linhas):\n\`\`\`typescript\n${schemaResult.data?.content?.slice(0, 2000)}\n\`\`\``;
    }

    let routesRef = "";
    const routesResult = await toolManager.execute("read_file", { path: "server/routes.ts", startLine: 1, endLine: 50 });
    if (routesResult.success) {
      routesRef = `\nREFERÊNCIA - server/routes.ts (primeiras 50 linhas):\n\`\`\`typescript\n${routesResult.data?.content?.slice(0, 1500)}\n\`\`\``;
    }

    await this.log(task.id, "generating", "Gerando código baseado na especificação...");

    const prompt = `Com base nesta especificação, gere o código completo:

ESPECIFICAÇÃO:
${JSON.stringify(spec, null, 2)}

CONTEXTO DO PROJETO:
${contextArtifact?.content?.slice(0, 2000) || "Não disponível"}

${schemaRef}
${routesRef}

Gere arquivos completos e funcionais para:
1. Schema do banco de dados (se necessário) - adicionar ao shared/schema.ts
2. Rotas da API - novo arquivo em server/ ou adicionar a routes.ts
3. Componente principal React - em client/src/pages/

Retorne em formato JSON com a estrutura:
{
  "files": [
    { "path": "caminho/completo.ts", "content": "código completo", "type": "tipo", "action": "create|modify" }
  ]
}

IMPORTANTE: Gere código completo e funcional, não use placeholders ou "// TODO".`;

    try {
      const response = await this.generateWithAI(prompt);

      let files: any[] = [];
      try {
        const jsonMatch = response.match(/\{[\s\S]*\}/);
        if (jsonMatch) {
          const parsed = JSON.parse(jsonMatch[0]);
          files = parsed.files || [];
        }
      } catch {
        files = [{
          path: `server/modules/${spec.moduleName || "generated"}/index.ts`,
          content: response,
          type: "module",
          action: "create"
        }];
      }

      for (const file of files) {
        await blackboardService.addArtifact(
          task.id,
          "code",
          file.path,
          file.content,
          "generator",
          { type: file.type, action: file.action }
        );
      }

      await this.log(task.id, "completed", `Gerados ${files.length} arquivos`);

      const mainTask = await blackboardService.getMainTask(task.id);
      if (mainTask) {
        await blackboardService.createSubtask(
          mainTask.id,
          "Validar código",
          "Validar e testar o código gerado",
          "validator",
          [task.id],
          { phase: "validation" }
        );
      }

      await blackboardService.completeTask(task.id, "generator", {
        filesGenerated: files.length,
        files: files.map(f => ({ path: f.path, type: f.type, action: f.action })),
      });
    } catch (error: any) {
      await blackboardService.failTask(task.id, "generator", error.message);
    }
  }
}

export const generatorAgent = new GeneratorAgent();
