-- Unified Tech Stack Recommendations Database Schema
-- Complete implementation for user-specific tech stack recommendations
-- Integrates with user-auth service for user management

-- Create the tech_stack_recommendations table with full user support
CREATE TABLE IF NOT EXISTS tech_stack_recommendations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    template_id UUID NOT NULL,
    template_type VARCHAR(50) NOT NULL,
    
    -- User and Session Information
    user_id UUID REFERENCES users(id) ON DELETE CASCADE, -- Links to user-auth service
    session_id VARCHAR(255),
    request_hash VARCHAR(64), -- Hash of request parameters for deduplication
    recommendation_type VARCHAR(50) DEFAULT 'user' CHECK (recommendation_type IN ('template', 'user', 'session')),
    
    -- Tech Stack Categories (JSONB for flexibility)
    frontend JSONB,
    backend JSONB,
    mobile JSONB,
    testing JSONB,
    ai_ml JSONB,
    devops JSONB,
    cloud JSONB,
    tools JSONB,
    
    -- Analysis Metadata
    analysis_context JSONB, -- Full context sent to AI
    confidence_scores JSONB, -- Confidence scores for each category
    reasoning JSONB, -- AI reasoning for recommendations
    ai_model VARCHAR(100) DEFAULT 'claude-3-5-sonnet-20241022',
    analysis_version VARCHAR(50) DEFAULT '1.0',
    
    -- Unified Data Storage
    user_context JSONB, -- User-specific context (business questions, preferences, etc.)
    unified_data JSONB, -- Store unified recommendations data
    source_services JSONB, -- Track which services contributed (claude, template, domain)
    
    -- Status and Tracking
    status VARCHAR(50) DEFAULT 'completed' CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
    error_message TEXT,
    processing_time_ms INTEGER,
    
    -- Expiration for session-based recommendations
    expires_at TIMESTAMP,
    
    -- Timestamps
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    last_analyzed_at TIMESTAMP DEFAULT NOW(),
    
    -- Constraints
    UNIQUE(template_id, template_type, user_id, recommendation_type)
);

-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_tech_stack_template_id ON tech_stack_recommendations (template_id);
CREATE INDEX IF NOT EXISTS idx_tech_stack_template_type ON tech_stack_recommendations (template_type);
CREATE INDEX IF NOT EXISTS idx_tech_stack_user_id ON tech_stack_recommendations (user_id);
CREATE INDEX IF NOT EXISTS idx_tech_stack_session_id ON tech_stack_recommendations (session_id);
CREATE INDEX IF NOT EXISTS idx_tech_stack_recommendation_type ON tech_stack_recommendations (recommendation_type);
CREATE INDEX IF NOT EXISTS idx_tech_stack_request_hash ON tech_stack_recommendations (request_hash);
CREATE INDEX IF NOT EXISTS idx_tech_stack_status ON tech_stack_recommendations (status);
CREATE INDEX IF NOT EXISTS idx_tech_stack_created_at ON tech_stack_recommendations (created_at DESC);
CREATE INDEX IF NOT EXISTS idx_tech_stack_last_analyzed ON tech_stack_recommendations (last_analyzed_at DESC);
CREATE INDEX IF NOT EXISTS idx_tech_stack_expires_at ON tech_stack_recommendations (expires_at);

-- GIN indexes for JSONB fields
CREATE INDEX IF NOT EXISTS idx_tech_stack_frontend_gin ON tech_stack_recommendations USING GIN (frontend);
CREATE INDEX IF NOT EXISTS idx_tech_stack_backend_gin ON tech_stack_recommendations USING GIN (backend);
CREATE INDEX IF NOT EXISTS idx_tech_stack_reasoning_gin ON tech_stack_recommendations USING GIN (reasoning);
CREATE INDEX IF NOT EXISTS idx_tech_stack_user_context_gin ON tech_stack_recommendations USING GIN (user_context);
CREATE INDEX IF NOT EXISTS idx_tech_stack_unified_data_gin ON tech_stack_recommendations USING GIN (unified_data);
CREATE INDEX IF NOT EXISTS idx_tech_stack_source_services_gin ON tech_stack_recommendations USING GIN (source_services);

-- Composite indexes for common queries
CREATE INDEX IF NOT EXISTS idx_tech_stack_user_template ON tech_stack_recommendations (user_id, template_id);
CREATE INDEX IF NOT EXISTS idx_tech_stack_user_type ON tech_stack_recommendations (user_id, recommendation_type);
CREATE INDEX IF NOT EXISTS idx_tech_stack_session_type ON tech_stack_recommendations (session_id, recommendation_type);

-- Apply update trigger
CREATE TRIGGER update_tech_stack_recommendations_updated_at 
    BEFORE UPDATE ON tech_stack_recommendations
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- Create a function to clean up expired user recommendations
CREATE OR REPLACE FUNCTION cleanup_expired_recommendations()
RETURNS INTEGER AS $$
DECLARE
    deleted_count INTEGER;
BEGIN
    DELETE FROM tech_stack_recommendations 
    WHERE expires_at IS NOT NULL 
    AND expires_at < NOW() 
    AND recommendation_type IN ('user', 'session');
    
    GET DIAGNOSTICS deleted_count = ROW_COUNT;
    
    IF deleted_count > 0 THEN
        RAISE NOTICE 'Cleaned up % expired recommendations', deleted_count;
    END IF;
    
    RETURN deleted_count;
END;
$$ LANGUAGE plpgsql;

-- Create a function to get user recommendations with fallback to template recommendations
CREATE OR REPLACE FUNCTION get_recommendations_for_user(
    p_template_id UUID,
    p_user_id UUID DEFAULT NULL,
    p_session_id VARCHAR DEFAULT NULL
)
RETURNS TABLE (
    id UUID,
    template_id UUID,
    template_type VARCHAR,
    user_id UUID,
    session_id VARCHAR,
    recommendation_type VARCHAR,
    frontend JSONB,
    backend JSONB,
    mobile JSONB,
    testing JSONB,
    ai_ml JSONB,
    devops JSONB,
    cloud JSONB,
    tools JSONB,
    unified_data JSONB,
    confidence_scores JSONB,
    reasoning JSONB,
    created_at TIMESTAMP,
    last_analyzed_at TIMESTAMP
) AS $$
BEGIN
    -- First try to get user-specific recommendations
    IF p_user_id IS NOT NULL THEN
        RETURN QUERY
        SELECT 
            tsr.id, tsr.template_id, tsr.template_type, tsr.user_id, tsr.session_id,
            tsr.recommendation_type, tsr.frontend, tsr.backend, tsr.mobile, tsr.testing,
            tsr.ai_ml, tsr.devops, tsr.cloud, tsr.tools, tsr.unified_data,
            tsr.confidence_scores, tsr.reasoning, tsr.created_at, tsr.last_analyzed_at
        FROM tech_stack_recommendations tsr
        WHERE tsr.template_id = p_template_id
        AND tsr.user_id = p_user_id
        AND tsr.recommendation_type = 'user'
        AND (tsr.expires_at IS NULL OR tsr.expires_at > NOW())
        ORDER BY tsr.created_at DESC
        LIMIT 1;
        
        -- If user-specific recommendation found, return it
        IF FOUND THEN
            RETURN;
        END IF;
    END IF;
    
    -- Try session-specific recommendations
    IF p_session_id IS NOT NULL THEN
        RETURN QUERY
        SELECT 
            tsr.id, tsr.template_id, tsr.template_type, tsr.user_id, tsr.session_id,
            tsr.recommendation_type, tsr.frontend, tsr.backend, tsr.mobile, tsr.testing,
            tsr.ai_ml, tsr.devops, tsr.cloud, tsr.tools, tsr.unified_data,
            tsr.confidence_scores, tsr.reasoning, tsr.created_at, tsr.last_analyzed_at
        FROM tech_stack_recommendations tsr
        WHERE tsr.template_id = p_template_id
        AND tsr.session_id = p_session_id
        AND tsr.recommendation_type = 'session'
        AND (tsr.expires_at IS NULL OR tsr.expires_at > NOW())
        ORDER BY tsr.created_at DESC
        LIMIT 1;
        
        -- If session-specific recommendation found, return it
        IF FOUND THEN
            RETURN;
        END IF;
    END IF;
    
    -- Fallback to template-based recommendations
    RETURN QUERY
    SELECT 
        tsr.id, tsr.template_id, tsr.template_type, tsr.user_id, tsr.session_id,
        tsr.recommendation_type, tsr.frontend, tsr.backend, tsr.mobile, tsr.testing,
        tsr.ai_ml, tsr.devops, tsr.cloud, tsr.tools, tsr.unified_data,
        tsr.confidence_scores, tsr.reasoning, tsr.created_at, tsr.last_analyzed_at
    FROM tech_stack_recommendations tsr
    WHERE tsr.template_id = p_template_id
    AND tsr.recommendation_type = 'template'
    ORDER BY tsr.created_at DESC
    LIMIT 1;
END;
$$ LANGUAGE plpgsql;

-- Create a function to get user recommendation statistics
CREATE OR REPLACE FUNCTION get_user_recommendation_stats(p_user_id UUID)
RETURNS TABLE (
    total_recommendations BIGINT,
    user_recommendations BIGINT,
    session_recommendations BIGINT,
    template_recommendations BIGINT,
    last_recommendation TIMESTAMP,
    most_used_template UUID
) AS $$
BEGIN
    RETURN QUERY
    SELECT 
        COUNT(*) as total_recommendations,
        COUNT(*) FILTER (WHERE recommendation_type = 'user') as user_recommendations,
        COUNT(*) FILTER (WHERE recommendation_type = 'session') as session_recommendations,
        COUNT(*) FILTER (WHERE recommendation_type = 'template') as template_recommendations,
        MAX(created_at) as last_recommendation,
        (
            SELECT template_id 
            FROM tech_stack_recommendations tsr2 
            WHERE tsr2.user_id = p_user_id 
            GROUP BY template_id 
            ORDER BY COUNT(*) DESC 
            LIMIT 1
        ) as most_used_template
    FROM tech_stack_recommendations tsr
    WHERE tsr.user_id = p_user_id;
END;
$$ LANGUAGE plpgsql;

-- Add comments for documentation
COMMENT ON TABLE tech_stack_recommendations IS 'Stores AI-generated tech stack recommendations for templates with user-specific support';
COMMENT ON COLUMN tech_stack_recommendations.user_id IS 'User ID for user-specific recommendations (NULL for template-based)';
COMMENT ON COLUMN tech_stack_recommendations.session_id IS 'Session ID for session-based recommendations';
COMMENT ON COLUMN tech_stack_recommendations.request_hash IS 'Hash of request parameters for deduplication';
COMMENT ON COLUMN tech_stack_recommendations.recommendation_type IS 'Type of recommendation: template, user, or session';
COMMENT ON COLUMN tech_stack_recommendations.user_context IS 'User-specific context and business requirements';
COMMENT ON COLUMN tech_stack_recommendations.unified_data IS 'Complete unified recommendations data';
COMMENT ON COLUMN tech_stack_recommendations.source_services IS 'Services that contributed to recommendations';
COMMENT ON COLUMN tech_stack_recommendations.expires_at IS 'Expiration time for user recommendations (NULL = permanent)';

-- Insert success message
SELECT 'Unified Tech Stack Recommendations database schema created successfully!' as message;
