"""
Database views for the library system.
These views combine data from multiple tables for efficient querying.
"""

from sqlalchemy import text
from sqlalchemy.orm import Session


def create_library_views(session: Session):
    """
    Create database views for the library system.
    These views combine downloaded documents with their classification and research data.
    """

    # View that combines Document with all related information
    # DevSkim: ignore DS137138 - SQL patterns 'http://%' are for URL parsing, not insecure URLs
    library_documents_enriched_view = """
    CREATE OR REPLACE VIEW library_documents_enriched AS
    SELECT
        -- Library document fields
        ld.id,
        ld.resource_id,
        ld.research_id,
        ld.document_hash,
        ld.file_path,
        ld.file_size,
        ld.file_type,
        ld.mime_type,
        ld.title as document_title,
        ld.authors,
        ld.published_date,
        ld.doi,
        ld.arxiv_id,
        ld.pmid,
        ld.pmcid,
        ld.download_status,
        ld.downloaded_at,
        ld.favorite,
        ld.tags,
        ld.notes,

        -- From ResearchResource
        rr.url as original_url,
        rr.source_type,
        rr.content_preview,
        rr.resource_metadata,

        -- Extract domain from URL (DevSkim: ignore DS137138 - URL pattern matching)
        CASE
            WHEN rr.url LIKE 'http://%' THEN -- DevSkim: ignore DS137138
                SUBSTRING(rr.url FROM 'http://([^/]+)') -- DevSkim: ignore DS137138
            WHEN rr.url LIKE 'https://%' THEN
                SUBSTRING(rr.url FROM 'https://([^/]+)')
            ELSE NULL
        END as domain,

        -- From ResearchHistory
        rh.title as research_title,
        rh.query as research_query,
        rh.mode as research_mode,
        rh.created_at as research_date,

        -- From DomainClassification (if exists)
        dc.category as domain_category,
        dc.subcategory as domain_subcategory,
        dc.confidence as classification_confidence,

        -- Special domain flags for filtering
        CASE
            WHEN rr.url LIKE '%arxiv.org%' THEN true
            ELSE false
        END as is_arxiv,

        CASE
            WHEN rr.url LIKE '%pubmed%' OR rr.url LIKE '%ncbi.nlm.nih.gov%' THEN true
            ELSE false
        END as is_pubmed,

        CASE
            WHEN rr.url LIKE '%semanticscholar.org%' THEN true
            ELSE false
        END as is_semantic_scholar,

        CASE
            WHEN ld.doi IS NOT NULL THEN true
            ELSE false
        END as has_doi,

        CASE
            WHEN ld.file_type = 'pdf' THEN true
            ELSE false
        END as is_pdf

    FROM library_documents ld
    INNER JOIN research_resources rr ON ld.resource_id = rr.id
    INNER JOIN research_history rh ON ld.research_id = rh.id
    LEFT JOIN domain_classifications dc ON
        dc.domain = CASE
            WHEN rr.url LIKE 'http://%' THEN -- DevSkim: ignore DS137138
                SUBSTRING(rr.url FROM 'http://([^/]+)') -- DevSkim: ignore DS137138
            WHEN rr.url LIKE 'https://%' THEN
                SUBSTRING(rr.url FROM 'https://([^/]+)')
            ELSE NULL
        END;
    """

    # View for research statistics (how many documents per research)
    # DevSkim: ignore DS137138 - SQL patterns 'http://%' are for URL parsing, not insecure URLs
    research_download_stats_view = """
    CREATE OR REPLACE VIEW research_download_stats AS
    SELECT
        rh.id as research_id,
        rh.title,
        rh.query,
        rh.mode,
        rh.created_at,
        rh.status,

        -- Count of resources
        COUNT(DISTINCT rr.id) as total_resources,

        -- Count of downloaded documents
        COUNT(DISTINCT ld.id) as downloaded_count,

        -- Download statistics
        SUM(CASE WHEN ld.download_status = 'completed' THEN 1 ELSE 0 END) as completed_downloads,
        SUM(CASE WHEN ld.download_status = 'failed' THEN 1 ELSE 0 END) as failed_downloads,
        SUM(CASE WHEN ld.download_status = 'pending' THEN 1 ELSE 0 END) as pending_downloads,

        -- File type breakdown
        SUM(CASE WHEN ld.file_type = 'pdf' THEN 1 ELSE 0 END) as pdf_count,
        SUM(CASE WHEN ld.file_type = 'html' THEN 1 ELSE 0 END) as html_count,

        -- Size statistics
        SUM(ld.file_size) as total_size_bytes,
        AVG(ld.file_size) as avg_size_bytes,

        -- Domain breakdown (DevSkim: ignore DS137138 - URL pattern matching)
        COUNT(DISTINCT
            CASE
                WHEN rr.url LIKE 'http://%' THEN -- DevSkim: ignore DS137138
                    SUBSTRING(rr.url FROM 'http://([^/]+)') -- DevSkim: ignore DS137138
                WHEN rr.url LIKE 'https://%' THEN
                    SUBSTRING(rr.url FROM 'https://([^/]+)')
                ELSE NULL
            END
        ) as unique_domains,

        -- Special sources
        SUM(CASE WHEN rr.url LIKE '%arxiv.org%' THEN 1 ELSE 0 END) as arxiv_count,
        SUM(CASE WHEN rr.url LIKE '%pubmed%' OR rr.url LIKE '%ncbi.nlm.nih.gov%' THEN 1 ELSE 0 END) as pubmed_count,
        SUM(CASE WHEN ld.doi IS NOT NULL THEN 1 ELSE 0 END) as doi_count,

        -- User rating if exists
        rr_rating.rating as user_rating,
        rr_rating.accuracy,
        rr_rating.completeness,
        rr_rating.relevance

    FROM research_history rh
    LEFT JOIN research_resources rr ON rr.research_id = rh.id
    LEFT JOIN library_documents ld ON ld.resource_id = rr.id
    LEFT JOIN research_ratings rr_rating ON rr_rating.research_id = rh.id
    GROUP BY
        rh.id, rh.title, rh.query, rh.mode, rh.created_at, rh.status,
        rr_rating.rating, rr_rating.accuracy, rr_rating.completeness, rr_rating.relevance;
    """

    # View for domain statistics
    # DevSkim: ignore DS137138 - SQL patterns 'http://%' are for URL parsing, not insecure URLs
    domain_download_stats_view = """
    CREATE OR REPLACE VIEW domain_download_stats AS
    SELECT
        -- DevSkim: ignore DS137138 - URL pattern matching for domain extraction
        CASE
            WHEN rr.url LIKE 'http://%' THEN -- DevSkim: ignore DS137138
                SUBSTRING(rr.url FROM 'http://([^/]+)') -- DevSkim: ignore DS137138
            WHEN rr.url LIKE 'https://%' THEN
                SUBSTRING(rr.url FROM 'https://([^/]+)')
            ELSE 'unknown'
        END as domain,

        dc.category as domain_category,
        dc.subcategory as domain_subcategory,

        COUNT(DISTINCT ld.id) as download_count,
        COUNT(DISTINCT ld.research_id) as research_count,
        SUM(ld.file_size) as total_size_bytes,
        AVG(ld.file_size) as avg_size_bytes,

        -- File types
        SUM(CASE WHEN ld.file_type = 'pdf' THEN 1 ELSE 0 END) as pdf_count,
        SUM(CASE WHEN ld.file_type = 'html' THEN 1 ELSE 0 END) as html_count,

        -- Success rate
        SUM(CASE WHEN ld.download_status = 'completed' THEN 1 ELSE 0 END) * 100.0 /
            NULLIF(COUNT(ld.id), 0) as success_rate

    FROM library_documents ld
    INNER JOIN research_resources rr ON ld.resource_id = rr.id
    LEFT JOIN domain_classifications dc ON
        dc.domain = CASE
            WHEN rr.url LIKE 'http://%' THEN -- DevSkim: ignore DS137138
                SUBSTRING(rr.url FROM 'http://([^/]+)') -- DevSkim: ignore DS137138
            WHEN rr.url LIKE 'https://%' THEN
                SUBSTRING(rr.url FROM 'https://([^/]+)')
            ELSE NULL
        END
    GROUP BY domain, dc.category, dc.subcategory
    ORDER BY download_count DESC;
    """

    try:
        # Create the views
        session.execute(text(library_documents_enriched_view))
        session.execute(text(research_download_stats_view))
        session.execute(text(domain_download_stats_view))
        session.commit()
        print("Library views created successfully")
    except Exception as e:
        session.rollback()
        print(f"Error creating views: {e}")
        raise


def drop_library_views(session: Session):
    """Drop the library views if they exist."""
    try:
        session.execute(
            text("DROP VIEW IF EXISTS library_documents_enriched CASCADE;")
        )
        session.execute(
            text("DROP VIEW IF EXISTS research_download_stats CASCADE;")
        )
        session.execute(
            text("DROP VIEW IF EXISTS domain_download_stats CASCADE;")
        )
        session.commit()
        print("Library views dropped successfully")
    except Exception as e:
        session.rollback()
        print(f"Error dropping views: {e}")
        raise
