CREATE TABLE IF NOT EXISTS hwlab_redeem_codes (
  id TEXT PRIMARY KEY,
  code_hash TEXT NOT NULL UNIQUE,
  code_prefix TEXT NOT NULL,
  display_name TEXT NOT NULL DEFAULT '',
  status TEXT NOT NULL DEFAULT 'active',
  credit_amount BIGINT NOT NULL,
  reason TEXT NOT NULL DEFAULT 'redeem',
  max_redemptions INTEGER NOT NULL DEFAULT 1,
  per_user_limit INTEGER NOT NULL DEFAULT 1,
  redeemed_count INTEGER NOT NULL DEFAULT 0,
  expires_at TIMESTAMPTZ,
  created_by_user_id TEXT,
  created_by_username TEXT,
  disabled_at TIMESTAMPTZ,
  metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CHECK (status IN ('active', 'disabled', 'expired')),
  CHECK (credit_amount > 0),
  CHECK (max_redemptions > 0),
  CHECK (per_user_limit > 0),
  CHECK (redeemed_count >= 0)
);

CREATE INDEX IF NOT EXISTS hwlab_redeem_codes_status_created_idx ON hwlab_redeem_codes(status, created_at DESC);
CREATE INDEX IF NOT EXISTS hwlab_redeem_codes_prefix_idx ON hwlab_redeem_codes(code_prefix);

CREATE TABLE IF NOT EXISTS hwlab_redeem_redemptions (
  id TEXT PRIMARY KEY,
  code_id TEXT NOT NULL REFERENCES hwlab_redeem_codes(id) ON DELETE CASCADE,
  user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
  ledger_id TEXT REFERENCES hwlab_credit_ledger(id) ON DELETE SET NULL,
  credit_amount BIGINT NOT NULL,
  status TEXT NOT NULL DEFAULT 'applied',
  idempotency_key TEXT UNIQUE,
  metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CHECK (credit_amount > 0),
  CHECK (status IN ('applied', 'rejected'))
);

CREATE INDEX IF NOT EXISTS hwlab_redeem_redemptions_code_created_idx ON hwlab_redeem_redemptions(code_id, created_at DESC);
CREATE INDEX IF NOT EXISTS hwlab_redeem_redemptions_user_created_idx ON hwlab_redeem_redemptions(user_id, created_at DESC);

CREATE TABLE IF NOT EXISTS hwlab_user_subscriptions (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
  plan_id TEXT NOT NULL REFERENCES hwlab_billing_plans(id),
  status TEXT NOT NULL DEFAULT 'active',
  source TEXT NOT NULL DEFAULT 'manual',
  current_period_start TIMESTAMPTZ,
  current_period_end TIMESTAMPTZ,
  metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CHECK (status IN ('active', 'trialing', 'past_due', 'canceled', 'disabled')),
  CHECK (source IN ('manual', 'redeem', 'payment_placeholder', 'system'))
);

CREATE INDEX IF NOT EXISTS hwlab_user_subscriptions_user_status_idx ON hwlab_user_subscriptions(user_id, status, created_at DESC);

CREATE TABLE IF NOT EXISTS hwlab_payment_orders (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL REFERENCES hwlab_users(id) ON DELETE CASCADE,
  provider TEXT NOT NULL DEFAULT 'unconfigured',
  status TEXT NOT NULL DEFAULT 'unconfigured',
  credit_amount BIGINT NOT NULL DEFAULT 0,
  amount_minor BIGINT NOT NULL DEFAULT 0,
  currency TEXT NOT NULL DEFAULT 'CNY',
  reason TEXT NOT NULL DEFAULT '',
  metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CHECK (status IN ('unconfigured', 'created', 'pending', 'paid', 'failed', 'cancelled', 'refunded')),
  CHECK (credit_amount >= 0),
  CHECK (amount_minor >= 0)
);

CREATE INDEX IF NOT EXISTS hwlab_payment_orders_user_created_idx ON hwlab_payment_orders(user_id, created_at DESC);
