import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
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_ARBITRATION_VOTE" || !body.params) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32600, message: "Invalid Request Structure" }
      }, { status: 400 });
    }

    const { arbitration_id, judge_id, vote_for, reasoning } = body.params;

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

    if (vote_for !== "BUILDER" && vote_for !== "EVALUATOR") {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32602, message: "vote_for must be BUILDER or EVALUATOR" }
      }, { status: 400 });
    }

    // Check if arbitration exists
    const arbitration = await prisma.arbitration.findUnique({
      where: { id: arbitration_id },
      include: { votes: true }
    });

    if (!arbitration) {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32001, message: "Arbitration not found" }
      }, { status: 404 });
    }

    if (arbitration.status !== "PENDING") {
      return NextResponse.json({
        jsonrpc: "2.0",
        error: { code: -32005, message: "Arbitration is already resolved" }
      }, { status: 400 });
    }

    // Record the vote
    try {
      await prisma.arbitrationVote.create({
        data: {
          arbitration_id,
          judge_id,
          vote_for,
          reasoning
        }
      });
    } catch (error: unknown) {
      if (typeof error === "object" && error !== null && "code" in error && error.code === "P2002") {
        return NextResponse.json({
          jsonrpc: "2.0",
          error: { code: -32006, message: "Judge has already voted" }
        }, { status: 400 });
      }
      throw error;
    }

    // Re-fetch votes to count
    const allVotes = await prisma.arbitrationVote.findMany({
      where: { arbitration_id }
    });

    let builderVotes = 0;
    let evaluatorVotes = 0;

    for (const v of allVotes) {
      if (v.vote_for === "BUILDER") builderVotes++;
      if (v.vote_for === "EVALUATOR") evaluatorVotes++;
    }

    // Check if we have a winner (2 votes)
    let winner: string | null = null;
    if (builderVotes >= 2) winner = "BUILDER";
    else if (evaluatorVotes >= 2) winner = "EVALUATOR";

    if (winner) {
      await prisma.arbitration.update({
        where: { id: arbitration_id },
        data: {
          status: "RESOLVED",
          winning_party: winner
        }
      });
      
      // Depending on winner, we update the task status!
      if (winner === "BUILDER") {
        await prisma.$transaction(async (tx) => {
          const task = await tx.task.findUnique({ where: { id: arbitration.task_id } });
          const builderAgentId = task?.builder_id;

          // Keep a single payout path here; legacy dividend/hostile-takeover logic is intentionally disabled
          // because the related schema models are not yet available in this release.
          if (builderAgentId) {
            await tx.agentProfile.findUnique({
              where: { agent_id: builderAgentId }
            });
          }

          await tx.task.update({
            where: { id: arbitration.task_id },
            data: { status: "COMPLETED" } // Force completion
          });
        });
      } else {
        const task = await prisma.task.update({
          where: { id: arbitration.task_id },
          data: { status: "FAILED" }, // Reject work
          select: { builder_id: true, scout_id: true }
        });

        // ==========================================
        // PHASE 20: SLASHING MECHANISM
        // If the Builder lost arbitration, we slash them!
        // ==========================================
        if (task.builder_id && task.scout_id) {
          const builder = await prisma.agentProfile.findUnique({ where: { agent_id: task.builder_id }});
          
          if (builder && builder.staked_amount > 0) {
            const slashAmount = Math.min(builder.staked_amount, 50000); // Up to 500 USDC
            const scoutReward = Math.floor(slashAmount / 2);
            const treasuryReward = slashAmount - scoutReward;
            const newStakedAmount = builder.staked_amount - slashAmount;
            const newTier = newStakedAmount >= 50000 ? "PREMIUM" : "BASIC";

            // Update builder stake
            await prisma.agentProfile.update({
              where: { agent_id: builder.agent_id },
              data: { staked_amount: newStakedAmount, tier: newTier }
            });

            // Create Slashing Event
            await prisma.slashingEvent.create({
              data: {
                agent_id: builder.agent_id,
                arbitration_id: arbitration.id,
                slashed_amount: slashAmount,
                scout_reward: scoutReward,
                treasury_reward: treasuryReward,
                reason: "Lost arbitration against evaluator"
              }
            });

            console.log(`[Slashing] Agent ${builder.agent_id} slashed ${slashAmount} cents!`);
          }
        }
      }

      return NextResponse.json({
        jsonrpc: "2.0",
        result: {
          message: `Vote casted. Arbitration resolved in favor of ${winner}.`,
          winner,
          votes_total: allVotes.length
        },
        id: body.id || null
      });
    }

    return NextResponse.json({
      jsonrpc: "2.0",
      result: {
        message: "Vote casted. Awaiting more judges.",
        current_votes: { BUILDER: builderVotes, EVALUATOR: evaluatorVotes }
      },
      id: body.id || null
    });

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