import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import Stripe from "stripe";
import { TaskStatus } from "@agent-bounty/contracts";
import { broadcastFomoEvent } from "@/lib/x-broadcaster";
import { sanitizeAgentId } from "@/lib/a2a-growth";
import { resolveA2aTrafficContext } from "@/lib/a2a-traffic";

const stripe = process.env.STRIPE_SECRET_KEY ? new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: "2026-05-27.dahlia",
}) : null;

function getStripeObjectId(value: string | Stripe.PaymentIntent | Stripe.SetupIntent | null) {
  if (typeof value === "string") return value;
  return value?.id || null;
}

async function handleDemandProposalFee(session: Stripe.Checkout.Session, requestHeaders: Headers) {
  const metadata = session.metadata || {};
  const taskId = metadata.task_id;
  const referralAgent = sanitizeAgentId(metadata.referral_agent);
  const proposalFeeCents = Number(metadata.proposal_fee_cents || session.amount_total || 0);
  const paymentIntentId = getStripeObjectId(session.payment_intent);
  const idempotencyKey = `proposal-fee:${session.id}`;
  const trafficContext = referralAgent
    ? resolveA2aTrafficContext(requestHeaders, referralAgent)
    : null;

  const task = await prisma.task.findFirst({
    where: taskId
      ? { id: taskId }
      : { stripe_checkout_session_id: session.id },
  });

  if (!task) {
    console.error(`[Webhook] Proposal task not found for session: ${session.id}`);
    return;
  }

  const existingCapture = await prisma.ledgerEntry.findUnique({
    where: { idempotency_key: idempotencyKey },
  });

  if (existingCapture) {
    console.log(`[Webhook] Duplicate proposal fee event ignored for session: ${session.id}`);
    return;
  }

  await prisma.$transaction(async (tx) => {
    await tx.ledgerEntry.create({
      data: {
        task_id: task.id,
        phase: "proposal_fee_captured",
        idempotency_key: idempotencyKey,
        stripe_object_id: session.id,
        response_status: "captured",
        http_status: 200,
      },
    });

    await tx.task.update({
      where: { id: task.id },
      data: {
        stripe_checkout_session_id: session.id,
        stripe_payment_intent_id: paymentIntentId,
        status: TaskStatus.DRAFT,
      },
    });

    if (referralAgent) {
      await tx.agentProfile.upsert({
        where: { agent_id: referralAgent },
        update: {
          discovery_source: "DEMAND_PROPOSAL_PAID_REFERRAL",
        },
        create: {
          agent_id: referralAgent,
          type: "SCOUT",
          status: "PENDING",
          discovery_source: "DEMAND_PROPOSAL_PAID_REFERRAL",
          capabilities: {
            growth_referral: true,
            source: metadata.source || "stripe-webhook",
          },
        },
      });

      await tx.scoutReputation.upsert({
        where: { scout_id: referralAgent },
        update: {
          successful_conversions: { increment: 1 },
        },
        create: {
          scout_id: referralAgent,
          successful_conversions: 1,
        },
      });

      const existingAffiliate = await tx.affiliateLedger.findFirst({
        where: {
          scout_id: referralAgent,
          task_id: task.id,
        },
      });

      if (!existingAffiliate && proposalFeeCents > 0) {
        await tx.affiliateLedger.create({
          data: {
            scout_id: referralAgent,
            task_id: task.id,
            amount: Math.floor(proposalFeeCents * 0.1),
            currency: "USD",
            status: "PENDING",
          },
        });
      }
    }

    await tx.auditEvent.create({
      data: {
        actorType: "SYSTEM",
        actorId: "stripe-webhook",
        action: "DEMAND_PROPOSAL_FEE_CAPTURED",
        entityType: "TASK",
        entityId: task.id,
        metadata: {
          stripe_session_id: session.id,
          stripe_payment_intent_id: paymentIntentId,
          fee_cents: proposalFeeCents,
          package_id: metadata.package_id || null,
          referral_agent: referralAgent || null,
          affiliate_fee_cents: referralAgent ? Math.floor(proposalFeeCents * 0.1) : 0,
          source: metadata.source || null,
          campaign: metadata.campaign || null,
        },
      },
    });

    if (referralAgent && trafficContext) {
      await tx.auditEvent.create({
        data: {
          actorType: trafficContext.actor_type,
          actorId: trafficContext.actor_id,
          action: "EXTERNAL_DEMAND_PROPOSAL_FEE_CAPTURED",
          entityType: "TASK",
          entityId: task.id,
          reason: "referred_demand_proposal_payment_captured",
          metadata: {
            stripe_session_id: session.id,
            stripe_payment_intent_id: paymentIntentId,
            fee_cents: proposalFeeCents,
            package_id: metadata.package_id || null,
            referral_agent: referralAgent,
            affiliate_fee_cents: Math.floor(proposalFeeCents * 0.1),
            source: metadata.source || null,
            campaign: metadata.campaign || null,
            request_id: trafficContext.request_id,
            source_ip: trafficContext.source_ip,
            user_agent: trafficContext.user_agent,
            is_public_ip: trafficContext.is_public_ip,
            surface: "stripe/webhook",
            request_actor_headers: trafficContext.request_actor_headers,
            response_status: 200,
            response_summary: "demand_proposal_fee_captured",
          },
        },
      });
    }
  });

  console.log(`[Webhook] Proposal fee captured for task ${task.id}. Payment Intent: ${paymentIntentId}`);
}

export async function POST(request: NextRequest) {
  const payload = await request.text();
  const signature = request.headers.get("stripe-signature");

  if (!signature || !process.env.STRIPE_WEBHOOK_SECRET) {
    return NextResponse.json({ error: "Missing signature or webhook secret" }, { status: 400 });
  }

  let event: Stripe.Event;

  try {
    if (!stripe) {
      throw new Error("Stripe SDK is not initialized");
    }
    event = stripe.webhooks.constructEvent(
      payload,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (error: unknown) {
    console.error("[Webhook Error]", error);
    return NextResponse.json({ error: "Webhook signature verification failed" }, { status: 400 });
  }

  try {
    if (event.type === "checkout.session.completed") {
      const session = event.data.object as Stripe.Checkout.Session;
      if (session.metadata?.intent === "DEMAND_PROPOSAL_FEE") {
        await handleDemandProposalFee(session, request.headers);
        return NextResponse.json({ received: true });
      }
      
      const task = await prisma.task.findFirst({
        where: { stripe_checkout_session_id: session.id }
      });

      if (!task) {
        console.error(`[Webhook] Task not found for session: ${session.id}`);
        return NextResponse.json({ received: true });
      }

      // Payment is authorized (Auth Hold)
      // Save the payment_intent_id and set status to OPEN
      await prisma.task.update({
        where: { id: task.id },
        data: {
          stripe_payment_intent_id: session.payment_intent as string,
          status: TaskStatus.OPEN
        }
      });
      
      console.log(`[Webhook] Task ${task.id} is now OPEN. Payment Intent: ${session.payment_intent}`);

      // High-Value Bounty FOMO trigger ($50 USD = 5000 cents)
      if (task.reward_amount >= 5000) {
        const formatted = task.reward_currency === "USD" 
          ? `$${(task.reward_amount / 100).toFixed(0)}` 
          : `NT$${task.reward_amount}`;
          
        void broadcastFomoEvent({
          type: "HIGH_VALUE_BOUNTY",
          taskId: task.id,
          amountFormatted: formatted
        });
      }
    }

    return NextResponse.json({ received: true });
  } catch (error: unknown) {
    console.error("[Webhook Processing Error]", error);
    return NextResponse.json({ error: "Internal Error" }, { status: 500 });
  }
}
