-- =====================================================
-- ORBIQUANT IA - SUBSCRIPTIONS TABLE
-- =====================================================
-- Description: User subscription management with Stripe integration
-- Schema: financial
-- =====================================================
-- DECISION: Planes en USD como moneda base
-- =====================================================

CREATE TABLE financial.subscriptions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,

  -- Plan y estado
  plan financial.subscription_plan NOT NULL,
  status financial.subscription_status NOT NULL DEFAULT 'incomplete',

  -- Stripe integration
  stripe_subscription_id VARCHAR(255) UNIQUE,
  stripe_customer_id VARCHAR(255),
  stripe_price_id VARCHAR(255),
  stripe_product_id VARCHAR(255),

  -- Pricing
  price DECIMAL(10,2) NOT NULL,
  currency financial.currency_code NOT NULL DEFAULT 'USD',
  billing_interval VARCHAR(20) NOT NULL DEFAULT 'month', -- month, year

  -- Billing periods
  current_period_start TIMESTAMPTZ,
  current_period_end TIMESTAMPTZ,
  trial_start TIMESTAMPTZ,
  trial_end TIMESTAMPTZ,

  -- Cancelación
  cancelled_at TIMESTAMPTZ,
  cancel_at_period_end BOOLEAN DEFAULT false,
  cancellation_reason TEXT,
  cancellation_feedback JSONB,

  -- Downgrade/Upgrade tracking
  previous_plan financial.subscription_plan,
  scheduled_plan financial.subscription_plan,
  scheduled_plan_effective_at TIMESTAMPTZ,

  -- Payment tracking
  last_payment_at TIMESTAMPTZ,
  next_payment_at TIMESTAMPTZ,
  failed_payment_count INTEGER DEFAULT 0,

  -- Features/Quotas (se pueden mover a tabla separada si crece)
  metadata JSONB DEFAULT '{}',

  -- Timestamps
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  ended_at TIMESTAMPTZ,

  -- Constraints
  CONSTRAINT positive_price CHECK (price >= 0),
  CONSTRAINT valid_billing_interval CHECK (billing_interval IN ('month', 'year')),
  CONSTRAINT trial_dates_order CHECK (
    (trial_start IS NULL AND trial_end IS NULL) OR
    (trial_start IS NOT NULL AND trial_end IS NOT NULL AND trial_start < trial_end)
  ),
  CONSTRAINT period_dates_order CHECK (
    (current_period_start IS NULL AND current_period_end IS NULL) OR
    (current_period_start IS NOT NULL AND current_period_end IS NOT NULL AND current_period_start < current_period_end)
  ),
  CONSTRAINT cancel_date_valid CHECK (
    (cancelled_at IS NULL) OR
    (cancelled_at >= created_at)
  ),
  CONSTRAINT ended_when_cancelled CHECK (
    (ended_at IS NULL) OR
    (cancelled_at IS NOT NULL AND ended_at >= cancelled_at)
  ),
  CONSTRAINT scheduled_plan_different CHECK (
    scheduled_plan IS NULL OR scheduled_plan != plan
  )
);

-- Indexes
CREATE INDEX idx_subscriptions_user_id ON financial.subscriptions(user_id);
CREATE INDEX idx_subscriptions_status ON financial.subscriptions(status);
CREATE INDEX idx_subscriptions_plan ON financial.subscriptions(plan);
CREATE INDEX idx_subscriptions_stripe_sub ON financial.subscriptions(stripe_subscription_id) WHERE stripe_subscription_id IS NOT NULL;
CREATE INDEX idx_subscriptions_stripe_customer ON financial.subscriptions(stripe_customer_id) WHERE stripe_customer_id IS NOT NULL;
CREATE INDEX idx_subscriptions_active ON financial.subscriptions(user_id, status) WHERE status = 'active';
CREATE INDEX idx_subscriptions_period_end ON financial.subscriptions(current_period_end) WHERE status = 'active';
CREATE INDEX idx_subscriptions_trial_end ON financial.subscriptions(trial_end) WHERE status = 'trialing';
CREATE INDEX idx_subscriptions_next_payment ON financial.subscriptions(next_payment_at) WHERE next_payment_at IS NOT NULL;

-- Unique constraint: un usuario solo puede tener una suscripción activa a la vez
CREATE UNIQUE INDEX idx_subscriptions_user_active ON financial.subscriptions(user_id)
  WHERE status IN ('active', 'trialing', 'past_due');

-- Comments
COMMENT ON TABLE financial.subscriptions IS 'User subscription management with Stripe integration';
COMMENT ON COLUMN financial.subscriptions.plan IS 'Subscription plan tier';
COMMENT ON COLUMN financial.subscriptions.status IS 'Subscription status (Stripe-compatible states)';
COMMENT ON COLUMN financial.subscriptions.price IS 'Subscription price in specified currency';
COMMENT ON COLUMN financial.subscriptions.billing_interval IS 'Billing frequency: month or year';
COMMENT ON COLUMN financial.subscriptions.cancel_at_period_end IS 'If true, subscription will cancel at end of current period';
COMMENT ON COLUMN financial.subscriptions.scheduled_plan IS 'Plan to switch to at scheduled_plan_effective_at';
COMMENT ON COLUMN financial.subscriptions.failed_payment_count IS 'Number of consecutive failed payment attempts';
COMMENT ON COLUMN financial.subscriptions.metadata IS 'Plan features, quotas, and additional configuration';
