/**
 * Agent Definitions Routes — Phase 6
 * Dev Center: Fábrica de Agentes (Design → Assemble → Deploy)
 */

import { Router, Request, Response } from "express";
import { db } from "../../db/index";
import { arcadiaAgentDefs, insertAgentDefSchema } from "@shared/schema";
import { eq, desc, and } from "drizzle-orm";
import { blackboardService } from "../blackboard/service";

const router = Router();

// GET /api/agent-defs — listar todos (filtro por status opcional)
router.get("/", async (req: Request, res: Response) => {
  try {
    const { status } = req.query;
    const tenantId = (req.user as any)?.tenantId?.toString() || null;

    let query = db.select().from(arcadiaAgentDefs).orderBy(desc(arcadiaAgentDefs.updatedAt));

    const defs = await query;

    const filtered = defs.filter(d => {
      const tenantMatch = !tenantId || !d.tenantId || d.tenantId === tenantId;
      const statusMatch = !status || d.status === status;
      return tenantMatch && statusMatch;
    });

    res.json({ success: true, data: filtered });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// GET /api/agent-defs/:id
router.get("/:id", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    const [def] = await db.select().from(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    if (!def) return res.status(404).json({ success: false, error: "Não encontrado" });
    res.json({ success: true, data: def });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs — criar
router.post("/", async (req: Request, res: Response) => {
  try {
    const userId = (req.user as any)?.id || "anonymous";
    const tenantId = (req.user as any)?.tenantId?.toString() || null;

    const parsed = insertAgentDefSchema.safeParse({ ...req.body, userId, tenantId });
    if (!parsed.success) {
      return res.status(400).json({ success: false, error: parsed.error.message });
    }

    const [created] = await db.insert(arcadiaAgentDefs).values(parsed.data).returning();
    res.json({ success: true, data: created });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// PATCH /api/agent-defs/:id — atualizar
router.patch("/:id", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    const { name, description, spec } = req.body;

    const updates: any = { updatedAt: new Date() };
    if (name !== undefined) updates.name = name;
    if (description !== undefined) updates.description = description;
    if (spec !== undefined) updates.spec = spec;

    const [updated] = await db
      .update(arcadiaAgentDefs)
      .set(updates)
      .where(eq(arcadiaAgentDefs.id, id))
      .returning();

    if (!updated) return res.status(404).json({ success: false, error: "Não encontrado" });
    res.json({ success: true, data: updated });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// DELETE /api/agent-defs/:id
router.delete("/:id", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    await db.delete(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    res.json({ success: true });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs/:id/assemble — montar via Blackboard
router.post("/:id/assemble", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    const userId = (req.user as any)?.id || "anonymous";

    const [def] = await db.select().from(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    if (!def) return res.status(404).json({ success: false, error: "Não encontrado" });

    const spec = def.spec as any;
    const specContent = spec?.content || JSON.stringify(spec);

    const task = await blackboardService.createMainTask(
      `Montar agente: ${def.name}`,
      specContent,
      userId,
      { agentDefId: id, spec, source: "agent-factory" }
    );

    await blackboardService.createSubtask(
      task.id,
      "Projetar agente",
      `Analisar spec e criar estrutura do agente: ${def.name}\n\n${specContent}`,
      "architect",
      [],
      { phase: "design", agentDefId: id }
    );

    const [updated] = await db
      .update(arcadiaAgentDefs)
      .set({ status: "assembling", lastTaskId: task.id, updatedAt: new Date() })
      .where(eq(arcadiaAgentDefs.id, id))
      .returning();

    res.json({ success: true, data: updated, taskId: task.id });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs/:id/deploy — marcar como deployed
router.post("/:id/deploy", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);

    const [def] = await db.select().from(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    if (!def) return res.status(404).json({ success: false, error: "Não encontrado" });
    if (def.status !== "ready") {
      return res.status(400).json({ success: false, error: "Agente precisa estar 'ready' para deploy" });
    }

    const [updated] = await db
      .update(arcadiaAgentDefs)
      .set({ status: "deployed", version: (def.version || 1) + 1, updatedAt: new Date() })
      .where(eq(arcadiaAgentDefs.id, id))
      .returning();

    res.json({ success: true, data: updated });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs/:id/redraft — volta para draft para remontar
router.post("/:id/redraft", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);

    const [updated] = await db
      .update(arcadiaAgentDefs)
      .set({ status: "draft", updatedAt: new Date() })
      .where(eq(arcadiaAgentDefs.id, id))
      .returning();

    if (!updated) return res.status(404).json({ success: false, error: "Não encontrado" });
    res.json({ success: true, data: updated });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs/:id/run — executar agente via Blackboard
router.post("/:id/run", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    const userId = (req.user as any)?.id || "anonymous";

    const [def] = await db.select().from(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    if (!def) return res.status(404).json({ success: false, error: "Não encontrado" });

    const spec = def.spec as any;
    const specContent = spec?.content || JSON.stringify(spec);

    const task = await blackboardService.createMainTask(
      `Executar agente: ${def.name}`,
      specContent,
      userId,
      { agentDefId: id, spec, source: "agent-run" }
    );

    await blackboardService.createSubtask(
      task.id,
      "Executar agente",
      `Executar o agente conforme spec:\n\n${specContent}`,
      "run-executor",
      [],
      { phase: "execution", agentDefId: id }
    );

    res.json({ success: true, taskId: task.id });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

// POST /api/agent-defs/:id/fork — duplicar como novo draft
router.post("/:id/fork", async (req: Request, res: Response) => {
  try {
    const id = parseInt(req.params.id);
    const userId = (req.user as any)?.id || "anonymous";
    const tenantId = (req.user as any)?.tenantId?.toString() || null;

    const [def] = await db.select().from(arcadiaAgentDefs).where(eq(arcadiaAgentDefs.id, id));
    if (!def) return res.status(404).json({ success: false, error: "Não encontrado" });

    const [forked] = await db.insert(arcadiaAgentDefs).values({
      name: `${def.name} (cópia)`,
      description: def.description,
      spec: def.spec as any,
      status: "draft",
      version: 1,
      tenantId,
      userId,
    }).returning();

    res.json({ success: true, data: forked });
  } catch (error: any) {
    res.status(500).json({ success: false, error: error.message });
  }
});

export default router;
