/**
 * Arcadia Suite - Executor Agent
 * 
 * Agente responsável por preparar código para staging (preview).
 * NÃO aplica código diretamente - envia para área de staging
 * onde o usuário pode revisar e aprovar antes de publicar.
 * 
 * @author Arcadia Development Team
 * @version 3.0.0 - Staging Flow
 */

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

const SYSTEM_PROMPT = `Você é o Agente Executor do Arcadia Suite.

## Seu Papel
Você prepara código validado para staging (preview), onde o usuário pode revisar antes de publicar.

## Processo de Staging
1. Verificar se validação passou
2. Validar caminhos dos arquivos
3. Marcar tarefa como "staged" (pronta para preview)
4. Aguardar aprovação do usuário para publicar

## IMPORTANTE
- NÃO aplique código diretamente ao projeto
- O código vai para STAGING primeiro
- O usuário decide quando publicar`;

const PROTECTED_FILES = [
  "server/routes.ts",
  "server/index.ts",
  "server/storage.ts",
  "server/db.ts",
  "shared/schema.ts",
  "client/src/App.tsx",
  "client/src/main.tsx",
  "client/src/pages/Cockpit.tsx",
  "client/src/pages/Agent.tsx",
  "client/src/pages/ProcessCompass.tsx",
  "client/src/pages/DevCenter.tsx",
  "package.json",
  "tsconfig.json",
  "vite.config.ts",
  "drizzle.config.ts",
];

export class ExecutorAgent extends BaseBlackboardAgent {
  constructor() {
    const config: AgentConfig = {
      name: "executor",
      displayName: "Agente Executor",
      description: "Prepara código para staging e publicação",
      systemPrompt: SYSTEM_PROMPT,
      capabilities: [
        "Preparar código para staging",
        "Validar caminhos de arquivos",
        "Bloquear arquivos protegidos",
        "Preparar para publicação"
      ],
      pollInterval: 2000
    };
    super(config);
  }

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

  async process(task: BlackboardTask): Promise<void> {
    await this.log(task.id, "thinking", "Preparando para staging...");

    const codeArtifacts = await blackboardService.getArtifactsForTask(task.id, "code");
    
    const allDocs = await blackboardService.getArtifactsForTask(task.id, "doc");
    const validationArtifact = allDocs.find(a => a.name === "validation-report.json");

    if (codeArtifacts.length === 0) {
      await blackboardService.failTask(task.id, "executor", "Nenhum código para aplicar");
      return;
    }

    let validation: any = { valid: false, score: 0 };
    if (validationArtifact?.content) {
      try {
        validation = JSON.parse(validationArtifact.content);
      } catch {}
    }

    if (!validation.valid || validation.score < 60) {
      await this.log(task.id, "blocked", `Validação falhou (score: ${validation.score}, valid: ${validation.valid})`);
      await blackboardService.failTask(task.id, "executor", `Código não aprovado (score: ${validation.score}) - staging bloqueado`);
      return;
    }

    await this.log(task.id, "executing", `Preparando ${codeArtifacts.length} arquivos para staging...`);

    const stagedFiles: string[] = [];
    const blockedFiles: string[] = [];
    const errors: string[] = [];

    for (const artifact of codeArtifacts) {
      const filePath = artifact.name;
      const content = artifact.content;

      if (!content) {
        errors.push(`${filePath}: conteúdo vazio`);
        continue;
      }

      if (PROTECTED_FILES.includes(filePath)) {
        blockedFiles.push(filePath);
        await this.log(task.id, "blocked", `Arquivo protegido: ${filePath} - não será incluído no staging`);
        continue;
      }

      const isValidPath = filePath.startsWith("client/src") || 
                          filePath.startsWith("server/") || 
                          filePath.startsWith("shared/");

      if (!isValidPath) {
        await this.log(task.id, "skipped", `Arquivo fora dos diretórios permitidos: ${filePath}`);
        continue;
      }

      stagedFiles.push(filePath);
    }

    if (stagedFiles.length === 0) {
      await blackboardService.failTask(task.id, "executor", `Nenhum arquivo válido para staging. Bloqueados: ${blockedFiles.join(", ")}. Erros: ${errors.join("; ")}`);
      return;
    }

    const mainTask = await blackboardService.getMainTask(task.id);

    const stagingReport = {
      action: "staging",
      status: "awaiting_approval",
      stagedFiles,
      blockedFiles,
      errors: errors.length > 0 ? errors : undefined,
      validationScore: validation.score,
      taskId: task.id,
      mainTaskId: mainTask?.id,
      title: mainTask?.title || task.title,
      stagedAt: new Date().toISOString(),
    };

    await blackboardService.addArtifact(
      task.id,
      "doc",
      "staging-report.json",
      JSON.stringify(stagingReport, null, 2),
      "executor"
    );

    await this.log(task.id, "completed", `Staging pronto: ${stagedFiles.length} arquivos aguardando aprovação no Preview`);

    if (mainTask) {
      await blackboardService.createSubtask(
        mainTask.id,
        "Registrar aprendizado",
        "Armazenar padrões aprendidos para evolução",
        "evolution",
        [task.id],
        { phase: "evolution" }
      );
    }

    await blackboardService.completeTask(task.id, "executor", stagingReport);
  }
}

export { PROTECTED_FILES };
export const executorAgent = new ExecutorAgent();
