export const dynamic = 'force-dynamic';
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import crypto from "crypto";
import axios from "axios";
import { cronUnauthorizedResponse, isCronRequestAuthorized } from "@/lib/cron-auth";

function getWebhookUrl(contactEndpoints: unknown) {
  const endpoints = typeof contactEndpoints === "string"
    ? JSON.parse(contactEndpoints)
    : contactEndpoints;

  if (typeof endpoints !== "object" || endpoints === null || Array.isArray(endpoints)) {
    return null;
  }

  const webhook = (endpoints as { webhook?: unknown }).webhook;
  return typeof webhook === "string" ? webhook : null;
}

export async function GET(request: Request) {
  if (!isCronRequestAuthorized(request)) {
    return cronUnauthorizedResponse("Bidding Evaluator");
  }

  console.log("[Bidding Evaluator] Running bidding evaluator cron...");

  try {
    // 1. Find all OPEN tasks that have PENDING bids
    const tasksWithBids = await prisma.task.findMany({
      where: {
        status: "OPEN",
        bid_proposals: {
          some: { status: "PENDING" }
        }
      },
      include: {
        bid_proposals: {
          where: { status: "PENDING" },
          include: {
            agent: {
              include: { scout_reputation: true }
            }
          }
        }
      }
    });

    const results = [];

    // 2. Evaluate bids for each task
    for (const task of tasksWithBids) {
      if (task.bid_proposals.length === 0) continue;

      // MVP Logic: Score = (1 - spam_score) * 100 - (proposed_reward / 100)
      // Actually simpler MVP: Sort by proposed_reward ASC, pick the first one where spam_score < 0.5
      // If none, pick the absolute lowest reward.

      const sortedBids = [...task.bid_proposals].sort((a, b) => {
        const aSpam = a.agent.scout_reputation?.spam_score || 0;
        const bSpam = b.agent.scout_reputation?.spam_score || 0;
        
        // Penalize high spam score
        const aScore = (1 - aSpam) * 10000 - a.proposed_reward;
        const bScore = (1 - bSpam) * 10000 - b.proposed_reward;

        return bScore - aScore; // Descending order of score
      });

      const winningBid = sortedBids[0];
      const losingBids = sortedBids.slice(1);

      // A2A Negotiation Logic
      // If the winning bid is higher than the task reward amount, but within 20%
      if (winningBid.proposed_reward > task.reward_amount) {
        if (winningBid.proposed_reward <= task.reward_amount * 1.2) {
          console.log(`[Bidding Evaluator] Bid ${winningBid.proposed_reward} exceeds budget ${task.reward_amount}. Proposing COUNTER_OFFER.`);
          
          await prisma.bidProposal.update({
            where: { id: winningBid.id },
            data: { 
              status: "NEGOTIATING",
              counter_offer_amount: task.reward_amount 
            }
          });

          // Dispatch Webhook to Builder Agent
          if (winningBid.agent.contact_endpoints) {
            const webhookUrl = getWebhookUrl(winningBid.agent.contact_endpoints);
            if (webhookUrl) {
              try {
                await axios.post(webhookUrl, {
                  jsonrpc: "2.0",
                  method: "A2A_COUNTER_OFFER",
                  params: {
                    task_id: task.id,
                    original_bid: winningBid.proposed_reward,
                    counter_offer: task.reward_amount,
                    currency: task.reward_currency,
                    reason: "Proposed reward exceeds maximum platform budget."
                  },
                  id: crypto.randomUUID()
                }, { timeout: 5000 });
                console.log(`[Bidding Evaluator] Dispatched COUNTER_OFFER to ${webhookUrl}`);
              } catch (error: unknown) {
                const message = error instanceof Error ? error.message : String(error);
                console.error(`[Bidding Evaluator] Failed to dispatch COUNTER_OFFER to ${webhookUrl}: ${message}`);
              }
            }
          }
          
          results.push({
            task_id: task.id,
            winner_agent_id: winningBid.agent_id,
            action: "COUNTER_OFFER",
            proposed: winningBid.proposed_reward,
            counter: task.reward_amount
          });
          continue;
        } else {
          console.log(`[Bidding Evaluator] Best bid ${winningBid.proposed_reward} way over budget. Rejecting all.`);
          for (const bid of sortedBids) {
            await prisma.bidProposal.update({
              where: { id: bid.id },
              data: { status: "REJECTED" }
            });
          }
          continue;
        }
      }

      await prisma.$transaction(async (tx) => {
        // Mark winning bid
        await tx.bidProposal.update({
          where: { id: winningBid.id },
          data: { status: "ACCEPTED" }
        });

        // Mark losing bids
        for (const loser of losingBids) {
          await tx.bidProposal.update({
            where: { id: loser.id },
            data: { status: "REJECTED" }
          });
        }

        // Assign task to winner
        await tx.task.update({
          where: { id: task.id },
          data: {
            status: "EXECUTING",
            builder_id: winningBid.agent_id
          }
        });

        // Create Claim
        await tx.claim.create({
          data: {
            task_id: task.id,
            agent_id: winningBid.agent_id,
            developer_wallet: winningBid.agent.wallet_address || "unknown",
            status: "EXECUTING",
            claim_token: crypto.randomUUID(),
            held_amount: winningBid.proposed_reward,
            held_currency: task.reward_currency,
            expires_at: new Date(Date.now() + 3600000)
          }
        });
      });

      results.push({
        task_id: task.id,
        winner_agent_id: winningBid.agent_id,
        action: "ACCEPTED",
        winning_reward: winningBid.proposed_reward,
        total_bids: task.bid_proposals.length
      });
      
      console.log(`[Bidding Evaluator] Task ${task.id} awarded to ${winningBid.agent_id} for ${winningBid.proposed_reward}`);
    }

    return NextResponse.json({
      success: true,
      evaluated_tasks: results.length,
      details: results
    });

  } catch (error: unknown) {
    console.error("[Bidding Evaluator] Error:", error);
    return NextResponse.json({ success: false, error: "Internal Server Error" }, { status: 500 });
  }
}
