-- Observability: AI credits metrics tables (Task 10)
-- Stores aggregated metrics for dashboard and monitoring

BEGIN;

-- Daily aggregated metrics for AI credits usage
CREATE TABLE ai_metrics_daily (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    metric_date DATE NOT NULL,
    
    -- Usage metrics
    total_requests INT NOT NULL DEFAULT 0,
    total_credits_charged INT NOT NULL DEFAULT 0,
    total_credits_refunded INT NOT NULL DEFAULT 0,
    
    -- Token metrics
    total_input_tokens BIGINT NOT NULL DEFAULT 0,
    total_output_tokens BIGINT NOT NULL DEFAULT 0,
    total_tokens BIGINT NOT NULL DEFAULT 0,
    
    -- Financial metrics
    total_revenue NUMERIC(12, 2) NOT NULL DEFAULT 0, -- From purchases
    estimated_cost NUMERIC(12, 6) NOT NULL DEFAULT 0, -- Computed from tokens
    estimated_margin NUMERIC(12, 2) NOT NULL DEFAULT 0, -- revenue - cost
    
    -- Error metrics
    failed_requests INT NOT NULL DEFAULT 0,
    timeout_requests INT NOT NULL DEFAULT 0,
    
    -- Unique users
    unique_active_users INT NOT NULL DEFAULT 0,
    new_wallet_creations INT NOT NULL DEFAULT 0,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    
    UNIQUE(metric_date)
);

-- Hourly metrics for more granular monitoring
CREATE TABLE ai_metrics_hourly (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    metric_hour TIMESTAMPTZ NOT NULL, -- Truncated to hour
    
    total_requests INT NOT NULL DEFAULT 0,
    total_credits_charged INT NOT NULL DEFAULT 0,
    avg_response_time_ms INT, -- Average response time in milliseconds
    error_count INT NOT NULL DEFAULT 0,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    
    UNIQUE(metric_hour)
);

-- Feature usage breakdown
CREATE TABLE ai_metrics_by_feature (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    metric_date DATE NOT NULL,
    feature_code VARCHAR(100) NOT NULL,
    
    request_count INT NOT NULL DEFAULT 0,
    credits_charged INT NOT NULL DEFAULT 0,
    unique_users INT NOT NULL DEFAULT 0,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    
    UNIQUE(metric_date, feature_code)
);

-- Model usage breakdown
CREATE TABLE ai_metrics_by_model (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    metric_date DATE NOT NULL,
    model_alias VARCHAR(100) NOT NULL,
    
    request_count INT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    estimated_cost NUMERIC(12, 6) NOT NULL DEFAULT 0,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    
    UNIQUE(metric_date, model_alias)
);

-- Indexes for metrics queries
CREATE INDEX idx_ai_metrics_daily_date ON ai_metrics_daily(metric_date DESC);
CREATE INDEX idx_ai_metrics_hourly_hour ON ai_metrics_hourly(metric_hour DESC);
CREATE INDEX idx_ai_metrics_feature ON ai_metrics_by_feature(metric_date DESC, feature_code);
CREATE INDEX idx_ai_metrics_model ON ai_metrics_by_model(metric_date DESC, model_alias);

-- Function to aggregate daily metrics
-- This should be called by a cron job daily
CREATE OR REPLACE FUNCTION aggregate_ai_metrics_daily(target_date DATE)
RETURNS VOID AS $$
BEGIN
    -- Insert or update daily aggregate
    INSERT INTO ai_metrics_daily (
        metric_date,
        total_requests,
        total_credits_charged,
        total_credits_refunded,
        total_input_tokens,
        total_output_tokens,
        total_tokens,
        failed_requests,
        unique_active_users
    )
    SELECT 
        target_date,
        COUNT(*),
        SUM(CASE WHEN status = 'success' THEN credits_charged ELSE 0 END),
        0, -- Refunds handled separately
        SUM(COALESCE(input_tokens, 0)),
        SUM(COALESCE(output_tokens, 0)),
        SUM(COALESCE(total_tokens, 0)),
        COUNT(CASE WHEN status = 'error' THEN 1 END),
        COUNT(DISTINCT user_id)
    FROM ai_usage_logs
    WHERE DATE(created_at) = target_date
    ON CONFLICT (metric_date) DO UPDATE SET
        total_requests = EXCLUDED.total_requests,
        total_credits_charged = EXCLUDED.total_credits_charged,
        total_input_tokens = EXCLUDED.total_input_tokens,
        total_output_tokens = EXCLUDED.total_output_tokens,
        total_tokens = EXCLUDED.total_tokens,
        failed_requests = EXCLUDED.failed_requests,
        unique_active_users = EXCLUDED.unique_active_users,
        updated_at = NOW();
    
    -- Aggregate by feature
    INSERT INTO ai_metrics_by_feature (metric_date, feature_code, request_count, credits_charged, unique_users)
    SELECT 
        target_date,
        feature_code,
        COUNT(*),
        SUM(credits_charged),
        COUNT(DISTINCT user_id)
    FROM ai_usage_logs
    WHERE DATE(created_at) = target_date
    GROUP BY feature_code
    ON CONFLICT (metric_date, feature_code) DO UPDATE SET
        request_count = EXCLUDED.request_count,
        credits_charged = EXCLUDED.credits_charged,
        unique_users = EXCLUDED.unique_users;
    
    -- Aggregate by model
    INSERT INTO ai_metrics_by_model (metric_date, model_alias, request_count, input_tokens, output_tokens)
    SELECT 
        target_date,
        model_alias,
        COUNT(*),
        SUM(COALESCE(input_tokens, 0)),
        SUM(COALESCE(output_tokens, 0))
    FROM ai_usage_logs
    WHERE DATE(created_at) = target_date
    GROUP BY model_alias
    ON CONFLICT (metric_date, model_alias) DO UPDATE SET
        request_count = EXCLUDED.request_count,
        input_tokens = EXCLUDED.input_tokens,
        output_tokens = EXCLUDED.output_tokens;
        
END;
$$ LANGUAGE plpgsql;

COMMIT;
