import type pg from 'pg';

interface EntitlementInput {
  tenantId: string;
  userId: string;
  days: number;
  regionId?: string | null;
  sourceType: string;
  sourceId?: string | null;
  legacySourceId?: string | null;
  metadata?: Record<string, unknown>;
}

export async function grantSvipEntitlement(client: pg.PoolClient, input: EntitlementInput) {
  const days = Math.trunc(input.days || 0);
  const expiresAtSql =
    days < 0 ? `'2099-12-31T23:59:59Z'::timestamptz` : `$8::timestamptz + ($9::text || ' days')::interval`;
  const scopeType = input.regionId ? 'region' : 'tenant';
  const startsAtResult = await client.query<{ starts_at: string }>(
    `
    select greatest(
      now(),
      coalesce(max(expires_at), now())
    ) as starts_at
    from public.entitlements
    where tenant_id = $1
      and user_id = $2
      and entitlement_type = 'svip'
      and scope_type = $3
      and (($4::uuid is null and scope_id is null) or scope_id = $4::uuid)
      and status = 'active'
    `,
    [input.tenantId, input.userId, scopeType, input.regionId || null],
  );

  const startsAt = startsAtResult.rows[0]?.starts_at;
  const result = await client.query(
    `
    insert into public.entitlements (
      tenant_id, user_id, entitlement_type, scope_type, scope_id,
      source_type, source_id, legacy_source_id, starts_at, expires_at, status, metadata
    )
    values (
      $1, $2, 'svip', $3, $4,
      $5, $6, $7, $8::timestamptz,
      ${expiresAtSql},
      'active', $10::jsonb
    )
    returning id, entitlement_type as "entitlementType", scope_type as "scopeType",
              scope_id as "scopeId", starts_at as "startsAt", expires_at as "expiresAt",
              status, metadata
    `,
    [
      input.tenantId,
      input.userId,
      scopeType,
      input.regionId || null,
      input.sourceType,
      input.sourceId || null,
      input.legacySourceId || null,
      startsAt,
      days,
      JSON.stringify(input.metadata || {}),
    ],
  );

  return result.rows[0];
}

export function createOrderNo(prefix = 'SVIP') {
  const now = new Date();
  const stamp = [
    now.getFullYear(),
    String(now.getMonth() + 1).padStart(2, '0'),
    String(now.getDate()).padStart(2, '0'),
    String(now.getHours()).padStart(2, '0'),
    String(now.getMinutes()).padStart(2, '0'),
    String(now.getSeconds()).padStart(2, '0'),
  ].join('');
  const random = Math.random().toString(36).slice(2, 8).toUpperCase();
  return `${prefix}${stamp}${random}`;
}

export function createRefundNo(prefix = 'RF') {
  return createOrderNo(prefix);
}
