#!/usr/bin/env bash
set -euo pipefail

# SQL 和缓存 key 组装 helper，供 remote acceptance 脚本复用。

sql_escape_literal() {
  local value="$1"
  local squote="'"
  value=${value//$squote/$squote$squote}
  printf '%s' "$value"
}

sql_literal() {
  printf "'%s'" "$(sql_escape_literal "$1")"
}

build_top_up_user_balance_sql() {
  local user_id="$1"
  local min_balance="$2"
  cat <<SQL
UPDATE users
SET balance = CASE WHEN balance < ${min_balance} THEN ${min_balance} ELSE balance END,
    updated_at = now()
WHERE id = ${user_id};
SQL
}

build_bind_api_key_group_sql() {
  local api_key="$1"
  local group_id="$2"
  cat <<SQL
UPDATE api_keys
SET group_id = ${group_id},
    updated_at = now()
WHERE key = $(sql_literal "$api_key");
SQL
}

build_api_key_auth_cache_key() {
  local api_key="$1"
  local digest
  digest="$(printf '%s' "$api_key" | sha256sum | awk '{print $1}')"
  printf 'apikey:auth:%s' "$digest"
}

build_user_balance_cache_key() {
  local user_id="$1"
  printf 'billing:balance:%s' "$user_id"
}

build_subscription_billing_cache_key() {
  local user_id="$1"
  local group_id="$2"
  printf 'billing:sub:%s:%s' "$user_id" "$group_id"
}

build_upsert_subscription_sql() {
  local user_id="$1"
  local group_id="$2"
  local duration_days="$3"
  local assigned_by="$4"
  local notes="$5"
  cat <<SQL
INSERT INTO user_subscriptions (
  user_id,
  group_id,
  starts_at,
  expires_at,
  status,
  assigned_by,
  assigned_at,
  notes,
  created_at,
  updated_at,
  deleted_at
)
VALUES (
  ${user_id},
  ${group_id},
  now(),
  now() + interval '$(sql_escape_literal "$duration_days") days',
  'active',
  ${assigned_by},
  now(),
  $(sql_literal "$notes"),
  now(),
  now(),
  NULL
)
ON CONFLICT (user_id, group_id) WHERE deleted_at IS NULL
DO UPDATE SET
  starts_at = EXCLUDED.starts_at,
  expires_at = EXCLUDED.expires_at,
  status = 'active',
  assigned_by = EXCLUDED.assigned_by,
  assigned_at = EXCLUDED.assigned_at,
  notes = EXCLUDED.notes,
  updated_at = now(),
  deleted_at = NULL;
SQL
}

build_subscription_access_prep_sql() {
  local user_id="$1"
  local api_key="$2"
  local group_id="$3"
  local min_balance="$4"
  local duration_days="$5"
  local assigned_by="$6"
  local notes="$7"

  cat <<SQL
BEGIN;
$(build_top_up_user_balance_sql "$user_id" "$min_balance")
$(build_bind_api_key_group_sql "$api_key" "$group_id")
$(build_upsert_subscription_sql "$user_id" "$group_id" "$duration_days" "$assigned_by" "$notes")
COMMIT;
SQL
}
