import "server-only";

import type { PoolConnection, RowDataPacket } from "mysql2/promise";
import { ensureOfficialMailSchema, getDbPool } from "@/lib/db";

export const DOMAIN_ASSISTANCE_BILLING_LOCK_ERROR =
  "domain-assistance-payment-method-locked";

type ActiveRequestRow = RowDataPacket & {
  id: number;
};

async function hasActiveRequestForOwnerUserId(
  ownerUserId: number,
  connection?: PoolConnection,
) {
  const executor = connection ?? getDbPool();
  const [rows] = await executor.query<ActiveRequestRow[]>(
    `
      SELECT id
      FROM domain_setup_assistance_requests
      WHERE user_id = ?
        AND status IN ('pending', 'in_progress')
      ORDER BY id DESC
      LIMIT 1
      ${connection ? "FOR UPDATE" : ""}
    `,
    [ownerUserId],
  );

  return Boolean(rows[0]);
}

export async function assertDomainAssistanceAllowsBillingChangesByOwnerEmail(
  ownerEmail: string,
) {
  await ensureOfficialMailSchema();
  const [rows] = await getDbPool().query<(RowDataPacket & { id: number })[]>(
    `
      SELECT id
      FROM users
      WHERE email = ?
      LIMIT 1
    `,
    [ownerEmail.trim().toLowerCase()],
  );
  const ownerUserId = Number(rows[0]?.id ?? 0);

  if (
    ownerUserId > 0 &&
    (await hasActiveRequestForOwnerUserId(ownerUserId))
  ) {
    throw new Error(DOMAIN_ASSISTANCE_BILLING_LOCK_ERROR);
  }
}

export async function assertDomainAssistanceAllowsBillingChangesForOwnerUserId(
  ownerUserId: number,
  connection: PoolConnection,
) {
  await connection.query("SELECT id FROM users WHERE id = ? FOR UPDATE", [
    ownerUserId,
  ]);

  if (await hasActiveRequestForOwnerUserId(ownerUserId, connection)) {
    throw new Error(DOMAIN_ASSISTANCE_BILLING_LOCK_ERROR);
  }
}
