import { Booking, WithdrawalRequest } from "@/db/models";
import { toNumber } from "@/lib/serialize";
import { isBookingsMysql, isWithdrawalsMysql } from "@/db/activeDatabase";
import type { RowDataPacket } from "mysql2/promise";

/** Completed payouts minus pending + approved withdrawal requests. */
export async function getOwnerAvailablePayoutTnd(ownerId: string) {
  let gross = 0;
  let reserved = 0;

  if (isBookingsMysql()) {
    const { connectMysql, mysqlPool, sqlQuery } = await import("@/db/mysql/pool");
    try {
      mysqlPool();
    } catch {
      await connectMysql();
    }
    const rows = await sqlQuery<Array<RowDataPacket & { owner_payout_tnd: number }>>(
      `SELECT COALESCE(SUM(owner_payout_tnd), 0) AS owner_payout_tnd
       FROM bookings
       WHERE owner_id = ? AND deleted_at IS NULL AND status = 'COMPLETED'`,
      [ownerId],
    );
    gross = toNumber((rows[0] as any)?.owner_payout_tnd);
  } else {
    const completed = await Booking.find({
      ownerId,
      deletedAt: null,
      status: "COMPLETED",
    })
      .select("ownerPayoutTnd")
      .lean();
    gross = completed.reduce((s, b) => s + toNumber(b.ownerPayoutTnd), 0);
  }

  if (isWithdrawalsMysql()) {
    const { listWithdrawalsMysql } = await import("@/db/mysql/withdrawals");
    const locked = await listWithdrawalsMysql({
      ownerId,
      statuses: ["PENDING", "APPROVED"],
      take: 5000,
    });
    reserved = locked.reduce((s, w) => s + toNumber(w.amountTnd), 0);
  } else {
    const locked = await WithdrawalRequest.find({
      ownerId,
      status: { $in: ["PENDING", "APPROVED"] },
    })
      .select("amountTnd")
      .lean();
    reserved = locked.reduce((s, w) => s + toNumber(w.amountTnd), 0);
  }

  return Math.max(0, Math.round((gross - reserved) * 100) / 100);
}
