import { Prisma } from "../../prisma/generated/client";
import Stripe from "stripe";

// Initialize Stripe with the secret key from env if available
const stripe = process.env.STRIPE_SECRET_KEY ? new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: "2026-05-27.dahlia", // Use latest or your specific API version
}) : null;

export async function authHold(
  tx: Prisma.TransactionClient,
  taskId: string,
  amount: number,
  currency: string,
  wallet: string,
  idempotencyKey: string
) {
  // Check idempotency
  const existing = await tx.ledgerEntry.findUnique({
    where: { idempotency_key: idempotencyKey },
  });
  if (existing) {
    if (existing.response_status === "SUCCESS") return existing;
    throw new Error(`Previous authHold failed for idempotencyKey: ${idempotencyKey}`);
  }

  // Check if we already have a payment intent for this task
  const task = await tx.task.findUnique({ where: { id: taskId } });
  if (!task || !task.stripe_payment_intent_id) {
    throw new Error("Task does not have a stripe_payment_intent_id. It must be created via Scout checkout first.");
  }

  // In Phase 1 real flow, the Auth Hold is done by the user before the task becomes OPEN.
  // When an AI claims the task, we don't actually create a new PaymentIntent.
  // We just verify the PaymentIntent has enough funds or is capturable.
  
  // To keep it simple, we just record that the claim successfully locked the existing intent
  return await tx.ledgerEntry.create({
    data: {
      task_id: taskId,
      phase: "AUTH_HOLD",
      idempotency_key: idempotencyKey,
      stripe_object_id: task.stripe_payment_intent_id,
      response_status: "SUCCESS",
      http_status: 200,
    },
  });
}

export async function capturePayment(
  tx: Prisma.TransactionClient,
  taskId: string,
  idempotencyKey: string
) {
  const existing = await tx.ledgerEntry.findUnique({
    where: { idempotency_key: idempotencyKey },
  });
  if (existing) {
    if (existing.response_status === "SUCCESS") return existing;
    throw new Error(`Previous capturePayment failed for idempotencyKey: ${idempotencyKey}`);
  }

  const task = await tx.task.findUnique({ where: { id: taskId } });
  if (!task || !task.stripe_payment_intent_id) {
    throw new Error("Cannot capture without a valid stripe_payment_intent_id on the task");
  }

  const claim = await tx.claim.findFirst({
    where: { task_id: taskId, status: "COMPLETED" },
    orderBy: { created_at: "desc" }
  });

  if (!claim) {
    throw new Error("Cannot capture without a COMPLETED claim");
  }

  let capturedIntent;
  try {
    if (!stripe) throw new Error("Stripe is not initialized");
    // Perform real Stripe capture
    capturedIntent = await stripe.paymentIntents.capture(task.stripe_payment_intent_id, undefined, {
      idempotencyKey
    });
  } catch (error: any) {
    // Record failed capture
    await tx.ledgerEntry.create({
      data: {
        task_id: taskId,
        phase: "CAPTURE",
        idempotency_key: idempotencyKey,
        stripe_object_id: task.stripe_payment_intent_id,
        response_status: "FAILED",
        http_status: error.statusCode || 500,
      },
    });
    throw error;
  }

  return await tx.ledgerEntry.create({
    data: {
      task_id: taskId,
      phase: "CAPTURE",
      idempotency_key: idempotencyKey,
      stripe_object_id: capturedIntent.id,
      response_status: "SUCCESS",
      http_status: 200,
    },
  });
}

export async function releasePayment(
  tx: Prisma.TransactionClient,
  taskId: string,
  idempotencyKey: string
) {
  const existing = await tx.ledgerEntry.findUnique({
    where: { idempotency_key: idempotencyKey },
  });
  if (existing) {
    if (existing.response_status === "SUCCESS") return existing;
    throw new Error(`Previous releasePayment failed for idempotencyKey: ${idempotencyKey}`);
  }

  const task = await tx.task.findUnique({ where: { id: taskId } });
  if (!task || !task.stripe_payment_intent_id) {
    return await tx.ledgerEntry.create({
      data: {
        task_id: taskId,
        phase: "RELEASE",
        idempotency_key: idempotencyKey,
        stripe_object_id: null,
        response_status: "SUCCESS",
        http_status: 200,
      },
    });
  }

  let canceledIntent;
  try {
    if (!stripe) throw new Error("Stripe is not initialized");
    canceledIntent = await stripe.paymentIntents.cancel(task.stripe_payment_intent_id, undefined, {
      idempotencyKey
    });
  } catch (error: any) {
    await tx.ledgerEntry.create({
      data: {
        task_id: taskId,
        phase: "RELEASE",
        idempotency_key: idempotencyKey,
        stripe_object_id: task.stripe_payment_intent_id,
        response_status: "FAILED",
        http_status: error.statusCode || 500,
      },
    });
    throw error;
  }

  return await tx.ledgerEntry.create({
    data: {
      task_id: taskId,
      phase: "RELEASE",
      idempotency_key: idempotencyKey,
      stripe_object_id: canceledIntent.id,
      response_status: "SUCCESS",
      http_status: 200,
    },
  });
}
