-- ============================================================================
-- INVESTMENT SCHEMA - Tabla: withdrawal_requests
-- ============================================================================
-- Solicitudes de retiro de cuentas PAMM
-- Requiere aprobacion manual para montos grandes
-- ============================================================================

-- Enum para estado de solicitud
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'withdrawal_status' AND typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'investment')) THEN
        CREATE TYPE investment.withdrawal_status AS ENUM (
            'pending',
            'under_review',
            'approved',
            'processing',
            'completed',
            'rejected',
            'cancelled'
        );
    END IF;
END$$;

CREATE TABLE IF NOT EXISTS investment.withdrawal_requests (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- Relaciones
    account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE RESTRICT,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,

    -- Solicitud
    request_number VARCHAR(20) NOT NULL UNIQUE,
    amount DECIMAL(20, 8) NOT NULL,
    currency VARCHAR(10) NOT NULL DEFAULT 'USD',

    -- Estado
    status investment.withdrawal_status NOT NULL DEFAULT 'pending',

    -- Destino del retiro
    destination_type VARCHAR(20) NOT NULL, -- 'wallet', 'bank', 'crypto'
    destination_details JSONB NOT NULL DEFAULT '{}',

    -- Fees
    fee_amount DECIMAL(20, 8) NOT NULL DEFAULT 0,
    fee_percentage DECIMAL(5, 2) NOT NULL DEFAULT 0,
    net_amount DECIMAL(20, 8) GENERATED ALWAYS AS (amount - fee_amount) STORED,

    -- Aprobacion
    requires_approval BOOLEAN NOT NULL DEFAULT FALSE,
    reviewed_by UUID REFERENCES auth.users(id),
    reviewed_at TIMESTAMPTZ,
    review_notes TEXT,

    -- Procesamiento
    processed_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    transaction_reference VARCHAR(100),

    -- Rechazo/Cancelacion
    rejection_reason TEXT,
    cancelled_at TIMESTAMPTZ,
    cancellation_reason TEXT,

    -- Metadata
    ip_address INET,
    user_agent TEXT,
    metadata JSONB DEFAULT '{}',

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

    -- Constraints
    CONSTRAINT chk_positive_amount CHECK (amount > 0),
    CONSTRAINT chk_valid_fee CHECK (fee_amount >= 0 AND fee_amount <= amount),
    CONSTRAINT chk_fee_percentage CHECK (fee_percentage >= 0 AND fee_percentage <= 100),
    CONSTRAINT chk_destination_type CHECK (destination_type IN ('wallet', 'bank', 'crypto'))
);

-- Indices
CREATE INDEX idx_withdrawal_requests_account ON investment.withdrawal_requests(account_id);
CREATE INDEX idx_withdrawal_requests_user ON investment.withdrawal_requests(user_id);
CREATE INDEX idx_withdrawal_requests_status ON investment.withdrawal_requests(status);
CREATE INDEX idx_withdrawal_requests_created ON investment.withdrawal_requests(created_at DESC);
CREATE INDEX idx_withdrawal_requests_pending ON investment.withdrawal_requests(status, created_at)
    WHERE status IN ('pending', 'under_review');

-- Comentarios
COMMENT ON TABLE investment.withdrawal_requests IS 'Solicitudes de retiro de cuentas PAMM';
COMMENT ON COLUMN investment.withdrawal_requests.request_number IS 'Numero unico de solicitud (WR-YYYYMMDD-XXXX)';
COMMENT ON COLUMN investment.withdrawal_requests.requires_approval IS 'True si el monto requiere aprobacion manual';
COMMENT ON COLUMN investment.withdrawal_requests.destination_details IS 'Detalles del destino (IBAN, wallet address, etc.)';

-- Funcion para generar numero de solicitud
CREATE OR REPLACE FUNCTION investment.generate_withdrawal_request_number()
RETURNS TRIGGER AS $$
DECLARE
    v_date TEXT;
    v_seq INTEGER;
BEGIN
    v_date := TO_CHAR(NOW(), 'YYYYMMDD');

    SELECT COALESCE(MAX(
        CAST(SUBSTRING(request_number FROM 'WR-[0-9]{8}-([0-9]+)') AS INTEGER)
    ), 0) + 1
    INTO v_seq
    FROM investment.withdrawal_requests
    WHERE request_number LIKE 'WR-' || v_date || '-%';

    NEW.request_number := 'WR-' || v_date || '-' || LPAD(v_seq::TEXT, 4, '0');
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tr_generate_withdrawal_request_number
    BEFORE INSERT ON investment.withdrawal_requests
    FOR EACH ROW
    WHEN (NEW.request_number IS NULL)
    EXECUTE FUNCTION investment.generate_withdrawal_request_number();
