-- =====================================================
-- ORBIQUANT IA - WALLET TRANSACTIONS TABLE
-- =====================================================
-- Description: Complete transaction history for all wallets
-- Schema: financial
-- =====================================================

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

  -- Wallet relacionada
  wallet_id UUID NOT NULL REFERENCES financial.wallets(id) ON DELETE RESTRICT,

  -- Tipo y estado
  transaction_type financial.transaction_type NOT NULL,
  status financial.transaction_status NOT NULL DEFAULT 'pending',

  -- Montos (precisión de 8 decimales)
  amount DECIMAL(20,8) NOT NULL,
  fee DECIMAL(15,8) DEFAULT 0,
  net_amount DECIMAL(20,8) GENERATED ALWAYS AS (amount - fee) STORED,

  -- Moneda
  currency financial.currency_code NOT NULL,

  -- Balances snapshot (para auditoría)
  balance_before DECIMAL(20,8),
  balance_after DECIMAL(20,8),

  -- Referencias externas
  stripe_payment_intent_id VARCHAR(255),
  stripe_transfer_id VARCHAR(255),
  stripe_charge_id VARCHAR(255),
  reference_id VARCHAR(100), -- ID de referencia interna (ej: trade_id, investment_id)

  -- Para transfers entre wallets
  destination_wallet_id UUID REFERENCES financial.wallets(id) ON DELETE RESTRICT,
  related_transaction_id UUID REFERENCES financial.wallet_transactions(id), -- TX relacionada (para transfers bidireccionales)

  -- Descripción y notas
  description TEXT,
  notes TEXT,
  metadata JSONB DEFAULT '{}',

  -- Procesamiento
  processed_at TIMESTAMPTZ,
  completed_at TIMESTAMPTZ,
  failed_at TIMESTAMPTZ,
  failed_reason TEXT,

  -- Idempotency
  idempotency_key VARCHAR(255) UNIQUE,

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

  -- Constraints
  CONSTRAINT positive_amount CHECK (amount > 0),
  CONSTRAINT positive_fee CHECK (fee >= 0),
  CONSTRAINT fee_lte_amount CHECK (fee <= amount),
  CONSTRAINT destination_for_transfers CHECK (
    (transaction_type IN ('transfer_in', 'transfer_out') AND destination_wallet_id IS NOT NULL) OR
    (transaction_type NOT IN ('transfer_in', 'transfer_out'))
  ),
  CONSTRAINT no_self_transfer CHECK (wallet_id != destination_wallet_id),
  CONSTRAINT completed_has_timestamp CHECK (
    (status = 'completed' AND completed_at IS NOT NULL) OR
    (status != 'completed')
  ),
  CONSTRAINT failed_has_reason CHECK (
    (status = 'failed' AND failed_reason IS NOT NULL AND failed_at IS NOT NULL) OR
    (status != 'failed')
  )
);

-- Indexes para performance y queries comunes
CREATE INDEX idx_wt_wallet_id ON financial.wallet_transactions(wallet_id);
CREATE INDEX idx_wt_transaction_type ON financial.wallet_transactions(transaction_type);
CREATE INDEX idx_wt_status ON financial.wallet_transactions(status);
CREATE INDEX idx_wt_created_at ON financial.wallet_transactions(created_at DESC);
CREATE INDEX idx_wt_reference_id ON financial.wallet_transactions(reference_id) WHERE reference_id IS NOT NULL;
CREATE INDEX idx_wt_stripe_payment ON financial.wallet_transactions(stripe_payment_intent_id) WHERE stripe_payment_intent_id IS NOT NULL;
CREATE INDEX idx_wt_stripe_transfer ON financial.wallet_transactions(stripe_transfer_id) WHERE stripe_transfer_id IS NOT NULL;
CREATE INDEX idx_wt_destination ON financial.wallet_transactions(destination_wallet_id) WHERE destination_wallet_id IS NOT NULL;
CREATE INDEX idx_wt_wallet_status_created ON financial.wallet_transactions(wallet_id, status, created_at DESC);
CREATE INDEX idx_wt_idempotency ON financial.wallet_transactions(idempotency_key) WHERE idempotency_key IS NOT NULL;

-- Composite index para queries de rango por wallet
CREATE INDEX idx_wt_wallet_date_range ON financial.wallet_transactions(wallet_id, created_at DESC)
  WHERE status = 'completed';

-- Comments
COMMENT ON TABLE financial.wallet_transactions IS 'Complete transaction history for all wallet operations';
COMMENT ON COLUMN financial.wallet_transactions.transaction_type IS 'Type of transaction: deposit, withdrawal, transfer, fee, etc.';
COMMENT ON COLUMN financial.wallet_transactions.net_amount IS 'Amount after fees (computed column)';
COMMENT ON COLUMN financial.wallet_transactions.reference_id IS 'Internal reference to related entity (trade, investment, etc.)';
COMMENT ON COLUMN financial.wallet_transactions.destination_wallet_id IS 'Target wallet for transfer operations';
COMMENT ON COLUMN financial.wallet_transactions.related_transaction_id IS 'Related transaction for bidirectional transfers';
COMMENT ON COLUMN financial.wallet_transactions.idempotency_key IS 'Unique key to prevent duplicate transactions';
COMMENT ON COLUMN financial.wallet_transactions.metadata IS 'Extensible JSON field for transaction-specific data';
