import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import axios from "axios";
import { a2aUnauthorizedResponse, isA2aRequestAuthorized } from "@/lib/a2a-auth";

export async function POST(request: Request) {
  if (!isA2aRequestAuthorized(request)) {
    return a2aUnauthorizedResponse();
  }

  try {
    const body = await request.json();

    if (body.jsonrpc !== "2.0" || body.method !== "A2A_DISPUTE_REQUEST" || !body.params) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32600, message: "Invalid Request Structure" }
      }, { status: 400 });
    }

    const { task_id, submission_id, initiator_id, evidence } = body.params;

    if (!task_id || !submission_id || !initiator_id) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32602, message: "Missing required parameters" }
      }, { status: 400 });
    }

    // Find the task and submission
    const task = await prisma.task.findUnique({
      where: { id: task_id },
      include: {
        builder_agent: true,
      }
    });

    if (!task || !task.builder_id || !task.created_by_agent) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32001, message: "Task not found or missing builder/evaluator" }
      }, { status: 404 });
    }

    // Determine who is initiating
    const isBuilder = initiator_id === task.builder_id;
    const isEvaluator = initiator_id === task.created_by_agent;

    if (!isBuilder && !isEvaluator) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32003, message: "Only the Builder or Evaluator can initiate a dispute" }
      }, { status: 403 });
    }

    // Run Code in Secure Sandbox for Proof-of-Execution
    let sandboxLogs = "";
    try {
      const { runInSandbox } = await import("@/lib/sandbox");
      const sandboxResult = await runInSandbox({
        task_id,
        agent_id: task.builder_id,
        code_snippet: evidence // Treating evidence as code snippet for demo
      });
      
      sandboxLogs = `\n\n--- SANDBOX PROOF OF EXECUTION ---\nVM ID: ${sandboxResult.vm_id}\nStatus: ${sandboxResult.status}\nExecution Time: ${sandboxResult.execution_time_ms}ms\nTest Pass Rate: ${(sandboxResult.test_pass_rate * 100).toFixed(0)}%\n\nSTDOUT:\n${sandboxResult.stdout}\n\nSTDERR:\n${sandboxResult.stderr}\n----------------------------------`;
    } catch (error: unknown) {
      console.error("[Sandbox] Failed to execute:", error);
      sandboxLogs = `\n\n--- SANDBOX ERROR ---\nCould not provision microVM for evaluation.\n---------------------`;
    }

    // Create the Arbitration record
    const arbitration = await prisma.arbitration.create({
      data: {
        task_id,
        builder_id: task.builder_id,
        evaluator_id: task.created_by_agent,
        status: "PENDING",
        builder_evidence: isBuilder ? (evidence + sandboxLogs) : null,
        evaluator_reason: isEvaluator ? (evidence + sandboxLogs) : null
      }
    });

    // Pick 3 random judge agents from the directory
    const judges = await prisma.agentProfile.findMany({
      where: {
        status: "WHITELISTED",
        agent_id: { notIn: [task.builder_id, task.created_by_agent] }
      },
      take: 3
    });

    if (judges.length === 0) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32004, message: "No available judges found in the registry" }
      }, { status: 503 });
    }

    // Notify judges
    for (const judge of judges) {
      const endpoints = judge.contact_endpoints as { webhook?: string } | null;
      if (endpoints?.webhook) {
        axios.post(endpoints.webhook, {
          jsonrpc: "2.0",
          method: "A2A_ARBITRATION_REQUEST",
          params: {
            arbitration_id: arbitration.id,
            task_id,
            submission_id,
            builder_evidence: arbitration.builder_evidence,
            evaluator_reason: arbitration.evaluator_reason
          }
        }).catch(err => {
          console.error(`[A2A Dispute] Failed to notify judge ${judge.agent_id}:`, err.message);
        });
      }
    }

    return NextResponse.json({
      jsonrpc: "2.0",
      result: {
        message: "Dispute initiated. Judges notified.",
        arbitration_id: arbitration.id,
        judges_notified: judges.length
      },
      id: body.id || null
    });

  } catch (error: unknown) {
    console.error("[A2A Dispute] Error:", error);
    return NextResponse.json({
      jsonrpc: "2.0",
      error: { code: -32000, message: "Server error" }
    }, { status: 500 });
  }
}
