import { NextRequest, NextResponse } from "next/server";
import { purchaseAirtime } from "@/utils/vtpass";
import { generateRequestId } from "@/utils/junkfunctions";
import {
  createTransaction,
  updateTransactionStatus,
} from "@/utils/transactions";
import { getServerSession } from "next-auth";
import { authOptions } from "@/auth";
import { User } from "@/models/user";
import dbConnect from "@/lib/connectdb";
import Transaction from "@/models/transactions";

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    if (!session) {
      return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
    }
    const { network, airtimeType, amount, phone, bypass, userEmail, userId } =
      await req.json();

    if (amount <= 0) {
      return NextResponse.json(
        { message: "Invalid amount. Must be greater than 0." },
        { status: 400 }
      );
    }

    // Map network to VTpass service ID
    const serviceID = network.toLowerCase(); // e.g., "mtn", "airtel"
    const request_id = await generateRequestId();
    const type = "AirtimeTransaction";
    const referenceId = request_id;

    let newAmount = amount;

    if (newAmount <= 0) {
      return NextResponse.json(
        { message: "Invalid amount. Must be greater than 0." },
        { status: 400 }
      );
    }

    await dbConnect();
    const duplicateWindow = 15000; // 15 seconds

    const user = await User.findOne({ email: session.user.email });
    const recentTransaction = await Transaction.findOne({
      userId: user._id.toString(),
      phone,
      network,
      airtimeType,
      status: { $in: ["Pending", "Successful"] },
      createdAt: { $gt: new Date(Date.now() - duplicateWindow) },
    });
    if (recentTransaction) {
      return NextResponse.json(
        {
          message:
            "Duplicate transaction detected. Please wait 15 seconds before trying again.",
          status: false,
        },
        { status: 429 }
      );
    }

    if (user.accountBalance >= amount) {
      const AirtimeTransactions = {
        userId,
        userEmail,
        type,
        amount: newAmount,
        referenceId,
        refund: false,
        status: "Pending",
        airtimeType,
        bypass,
        mobileNumber: phone,
        network,
        discoName: "",
      };

      const transaction = await createTransaction(AirtimeTransactions);

      const blockedPhones = [
        "09037303701",
        "9037303701",
        "09068549724",
        "9068549724",
        "2349037303701",
        "2347034366438",
        "7034366438",
        "07034366438",
        "2349068549724",
        "9068549724",
        "09037788220",
        "9037788220",
        "2349037788220",
      ];

      const isBlockedPhone = (phone: string): boolean => {
        const cleanedPhone = phone.replace(/\s+/g, ""); // remove any whitespace
        return blockedPhones.includes(cleanedPhone);
      };

      if (isBlockedPhone(phone)) {
        throw new Error(
          "Transaction blocked: suspicious phone number detected."
        );
      }
      const result = await purchaseAirtime({
        request_id,
        serviceID,
        phone,
        amount,
      });

      if (
        result.code === "000" &&
        result.content.transactions.status === "delivered"
      ) {
        transaction.status = "Successful";
      } else if (
        result.code === "000" &&
        result.content.transactions.status === "pending"
      ) {
        transaction.status = "Pending";
      } else if (
        result.code === "016" &&
        result.content.transactions.status === "failed"
      ) {
        transaction.status = "Failed";
      }
      const response = result;
      await updateTransactionStatus(
        referenceId,
        type,
        transaction.status,
        newAmount,
        transaction.token || ""
      );

      return NextResponse.json(response, { status: 200 });
    } else {
      return NextResponse.json(
        { message: "Insufficient Balance" },
        { status: 401 }
      );
    }
  } catch (error) {
    return NextResponse.json(
      { error: "Failed to process request" },
      { status: 500 }
    );
  }
}
