-- =====================================================
-- ORBIQUANT IA - PAYMENTS TABLE
-- =====================================================
-- Description: Payment transaction records
-- Schema: financial
-- =====================================================

CREATE TABLE financial.payments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

  -- Referencias
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,
  subscription_id UUID REFERENCES financial.subscriptions(id) ON DELETE SET NULL,
  invoice_id UUID REFERENCES financial.invoices(id) ON DELETE SET NULL,
  wallet_transaction_id UUID REFERENCES financial.wallet_transactions(id) ON DELETE SET NULL,

  -- Stripe integration
  stripe_payment_intent_id VARCHAR(255) UNIQUE,
  stripe_charge_id VARCHAR(255),
  stripe_payment_method_id VARCHAR(255),

  -- Payment details
  amount DECIMAL(15,2) NOT NULL,
  currency financial.currency_code NOT NULL,
  payment_method financial.payment_method NOT NULL,
  status financial.payment_status NOT NULL DEFAULT 'pending',

  -- Descripción
  description TEXT,
  statement_descriptor VARCHAR(255), -- Lo que ve el usuario en su estado de cuenta

  -- Refunds
  refunded BOOLEAN DEFAULT false,
  refund_amount DECIMAL(15,2),
  refund_reason TEXT,
  refunded_at TIMESTAMPTZ,

  -- Metadata
  metadata JSONB DEFAULT '{}',

  -- Error handling
  failure_code VARCHAR(100),
  failure_message TEXT,

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

  -- Constraints
  CONSTRAINT positive_amount CHECK (amount > 0),
  CONSTRAINT positive_refund CHECK (refund_amount IS NULL OR refund_amount > 0),
  CONSTRAINT refund_lte_amount CHECK (refund_amount IS NULL OR refund_amount <= amount),
  CONSTRAINT refunded_has_data CHECK (
    (refunded = false AND refund_amount IS NULL AND refunded_at IS NULL) OR
    (refunded = true AND refund_amount IS NOT NULL AND refunded_at IS NOT NULL)
  ),
  CONSTRAINT succeeded_has_timestamp CHECK (
    (status = 'succeeded' AND succeeded_at IS NOT NULL) OR
    (status != 'succeeded')
  ),
  CONSTRAINT failed_has_data CHECK (
    (status = 'failed' AND failed_at IS NOT NULL) OR
    (status != 'failed')
  )
);

-- Indexes
CREATE INDEX idx_payments_user_id ON financial.payments(user_id);
CREATE INDEX idx_payments_subscription_id ON financial.payments(subscription_id) WHERE subscription_id IS NOT NULL;
CREATE INDEX idx_payments_invoice_id ON financial.payments(invoice_id) WHERE invoice_id IS NOT NULL;
CREATE INDEX idx_payments_status ON financial.payments(status);
CREATE INDEX idx_payments_stripe_intent ON financial.payments(stripe_payment_intent_id) WHERE stripe_payment_intent_id IS NOT NULL;
CREATE INDEX idx_payments_created_at ON financial.payments(created_at DESC);
CREATE INDEX idx_payments_user_created ON financial.payments(user_id, created_at DESC);
CREATE INDEX idx_payments_payment_method ON financial.payments(payment_method);
CREATE INDEX idx_payments_refunded ON financial.payments(refunded) WHERE refunded = true;

-- Comments
COMMENT ON TABLE financial.payments IS 'Payment transaction records with Stripe integration';
COMMENT ON COLUMN financial.payments.stripe_payment_intent_id IS 'Stripe PaymentIntent ID';
COMMENT ON COLUMN financial.payments.payment_method IS 'Payment method used: card, bank_transfer, crypto, etc.';
COMMENT ON COLUMN financial.payments.statement_descriptor IS 'Text shown on customer bank statement';
COMMENT ON COLUMN financial.payments.wallet_transaction_id IS 'Related wallet transaction if payment funds a wallet';
COMMENT ON COLUMN financial.payments.metadata IS 'Additional payment metadata and context';
