from flask import current_app, url_for
from sqlalchemy.exc import SQLAlchemyError

from common.extensions import db
from common.models.document import Catalog, Document, DocumentVersion, Processor, Retriever


def get_catalogs_list_view():
    """Genereer de catalogi lijst-weergave configuratie"""
    # Haal alle catalogi op (geen server-side filtering - wordt client-side afgehandeld)
    catalog_query = Catalog.query.order_by(Catalog.id)
    all_catalogs = catalog_query.all()

    # Bereid data voor voor Tabulator
    data = []
    for catalog in all_catalogs:
        data.append({
            'id': catalog.id,
            'name': catalog.name,
            'type': catalog.type
        })

    # Kolomdefinities
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Naam', 'field': 'name'},
        {'title': 'Type', 'field': 'type'},
    ]

    actions = [
        {'value': 'set_session_catalog', 'text': 'Set Session Catalog', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'edit_catalog', 'text': 'Edit Catalog', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_catalog', 'text': 'Register Catalog', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

    initial_sort = [{'column': 'id', 'dir': 'asc'}]

    return {
        'title': 'Catalogi',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'catalogs_table',
        'form_action': url_for('document_bp.handle_catalog_selection'),
        'description': 'Bekijk en beheer catalogi'
    }


def get_processors_list_view(catalog_id):
    """Generate the processors list view configuration"""
    # Get all processors for this catalog
    processor_query = Processor.query.filter_by(catalog_id=catalog_id).order_by(Processor.id)
    all_processors = processor_query.all()
    
    # Prepare data for Tabulator
    data = []
    for processor in all_processors:
        data.append({
            'id': processor.id,
            'name': processor.name,
            'type': processor.type,
            'active': processor.active
        })
    
    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'Type', 'field': 'type'},
        {'title': 'Active', 'field': 'active'}
    ]
    
    actions = [
        {'value': 'edit_processor', 'text': 'Edit Processor', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_processor', 'text': 'Register Processor', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]
    
    initial_sort = [{'column': 'id', 'dir': 'asc'}]
    
    return {
        'title': 'Processors',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'processors_table',
        'form_action': url_for('document_bp.handle_processor_selection'),
        'description': 'View and manage processors'
    }


def get_retrievers_list_view(catalog_id):
    """Generate the retrievers list view configuration"""
    # Get all retrievers for this catalog
    retriever_query = Retriever.query.filter_by(catalog_id=catalog_id).order_by(Retriever.id)
    all_retrievers = retriever_query.all()
    
    # Prepare data for Tabulator
    data = []
    for retriever in all_retrievers:
        data.append({
            'id': retriever.id,
            'name': retriever.name,
            'type': retriever.type
        })
    
    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'Type', 'field': 'type'}
    ]
    
    actions = [
        {'value': 'edit_retriever', 'text': 'Edit Retriever', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_retriever', 'text': 'Register Retriever', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]
    
    initial_sort = [{'column': 'id', 'dir': 'asc'}]
    
    return {
        'title': 'Retrievers',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'retrievers_table',
        'form_action': url_for('document_bp.handle_retriever_selection'),
        'description': 'View and manage retrievers'
    }


def get_documents_list_view(catalog_id):
    # Query all documents for the given catalog_id, along with their latest version
    # We use a subquery to get the latest document version for each document
    from sqlalchemy import desc, func
    from sqlalchemy.orm import aliased

    # Subquery to get the max version id for each document
    latest_version_subquery = db.session.query(
        DocumentVersion.doc_id,
        func.max(DocumentVersion.id).label('max_id')
    ).group_by(DocumentVersion.doc_id).subquery()

    # Alias for the latest document version
    LatestVersion = aliased(DocumentVersion)

    # Main query with join to get documents with their latest version
    document_query = db.session.query(
        Document.id, 
        Document.name, 
        Document.valid_from, 
        Document.valid_to,
        LatestVersion.file_type,
        LatestVersion.file_size,
        LatestVersion.processing
    ).join(
        latest_version_subquery,
        Document.id == latest_version_subquery.c.doc_id
    ).join(
        LatestVersion,
        (LatestVersion.doc_id == latest_version_subquery.c.doc_id) & 
        (LatestVersion.id == latest_version_subquery.c.max_id)
    ).filter(
        Document.catalog_id == catalog_id
    ).order_by(Document.id)

    # Execute the query
    try:
        documents_with_latest_versions = document_query.all()

        # Prepare data for Tabulator
        data = []
        for doc in documents_with_latest_versions:
            data.append({
                'id': doc.id,
                'name': doc.name,
                'valid_from': doc.valid_from.strftime('%Y-%m-%d') if doc.valid_from else '',
                'valid_to': doc.valid_to.strftime('%Y-%m-%d') if doc.valid_to else '',
                'file_type': doc.file_type,
                'file_size': f"{doc.file_size:.2f}" if doc.file_size else '',
            })

        # Column definitions
        columns = [
            {'title': 'ID', 'field': 'id', 'width': 80},
            {'title': 'Name', 'field': 'name'},
            {'title': 'Valid From', 'field': 'valid_from'},
            {'title': 'Valid To', 'field': 'valid_to'},
            {'title': 'File Type', 'field': 'file_type'},
            {'title': 'File Size', 'field': 'file_size'},
        ]

        actions = [
            {'value': 'edit_document', 'text': 'Edit Document', 'class': 'btn-primary', 'requiresSelection': True},
            {'value': 'edit_document_version', 'text': 'Edit Document Version', 'class': 'btn-secondary',
             'requiresSelection': True},
            {'value': 'refresh', 'text': 'Refresh', 'class': 'btn-secondary', 'requiresSelection': True},
            {'value': 're_process', 'text': 'Re-Process', 'class': 'btn-secondary', 'requiresSelection': True},
            {'value': 'view_document_markdown', 'text': 'View Document', 'class': 'btn-secondary', 'requiresSelection': True},
        ]

        initial_sort = [{'column': 'id', 'dir': 'asc'}]

        return {
            'title': 'Documents',
            'data': data,
            'columns': columns,
            'actions': actions,
            'initial_sort': initial_sort,
            'table_id': 'documents_table',
            'form_action': url_for('document_bp.handle_document_selection'),
            'description': 'Manage Documents and Document Versions'
        }

    except SQLAlchemyError as e:
        current_app.logger.error(f"Error querying documents with latest versions: {str(e)}")
        return {
            'title': 'Documents',
            'data': [],
            'columns': [],
            'actions': [],
            'initial_sort': [],
            'table_id': 'documents_table',
            'form_action': url_for('document_bp.handle_document_selection'),
            'description': 'There was an error while retrieving the documents. Please try again later.'
        }


def get_documents_processing_list_view(catalog_id):
    # Query all documents for the given catalog_id, along with their latest version
    # We use a subquery to get the latest document version for each document
    from sqlalchemy import desc, func
    from sqlalchemy.orm import aliased

    # Subquery to get the max version id for each document
    latest_version_subquery = db.session.query(
        DocumentVersion.doc_id,
        func.max(DocumentVersion.id).label('max_id')
    ).group_by(DocumentVersion.doc_id).subquery()

    # Alias for the latest document version
    LatestVersion = aliased(DocumentVersion)

    # Main query with join to get documents with their latest version
    document_query = db.session.query(
        Document.id,
        Document.name,
        LatestVersion.processing,
        LatestVersion.processing_started_at,
        LatestVersion.processing_finished_at,
        LatestVersion.processing_error,
    ).join(
        latest_version_subquery,
        Document.id == latest_version_subquery.c.doc_id
    ).join(
        LatestVersion,
        (LatestVersion.doc_id == latest_version_subquery.c.doc_id) &
        (LatestVersion.id == latest_version_subquery.c.max_id)
    ).filter(
        Document.catalog_id == catalog_id
    ).order_by(Document.id)

    # Execute the query
    try:
        documents_with_latest_versions = document_query.all()

        # Prepare data for Tabulator
        data = []
        for doc in documents_with_latest_versions:
            data.append({
                'id': doc.id,
                'name': doc.name,
                'processing_finished': not doc.processing,
                'processing_started_at': doc.processing_started_at.strftime('%Y-%m-%d %H:%M:%S') if doc.processing_started_at else '',
                'processing_finished_at': doc.processing_finished_at.strftime('%Y-%m-%d %H:%M:%S') if doc.processing_finished_at else '',
                'processing_error': doc.processing_error,
            })

        # Column definitions
        columns = [
            {'title': 'ID', 'field': 'id', 'width': 80},
            {'title': 'Name', 'field': 'name'},
            {'title': 'Finished Processing', 'field': 'processing_finished', 'formatter': 'tickCross'},
            {'title': 'Start', 'field': 'processing_started_at'},
            {'title': 'Finish', 'field': 'processing_finished_at'},
            {'title': 'Error', 'field': 'processing_error'},
        ]

        actions = [
            {'value': 'edit_document', 'text': 'Edit Document', 'class': 'btn-primary', 'requiresSelection': True},
            {'value': 'edit_document_version', 'text': 'Edit Document Version', 'class': 'btn-secondary',
             'requiresSelection': True},
            {'value': 'refresh', 'text': 'Refresh', 'class': 'btn-secondary', 'requiresSelection': True},
            {'value': 're_process', 'text': 'Re-Process', 'class': 'btn-secondary', 'requiresSelection': True},
            {'value': 'view_document_markdown', 'text': 'View Document', 'class': 'btn-secondary', 'requiresSelection': True},
        ]

        initial_sort = [{'column': 'id', 'dir': 'asc'}]

        return {
            'title': 'Document Processing Status',
            'data': data,
            'columns': columns,
            'actions': actions,
            'initial_sort': initial_sort,
            'table_id': 'documents_table',
            'form_action': url_for('document_bp.handle_document_selection'),
            'description': 'View Processing Status of Document Versions'
        }

    except SQLAlchemyError as e:
        current_app.logger.error(f"Error querying documents with latest versions: {str(e)}")
        return {
            'title': 'Document Processing Status',
            'data': [],
            'columns': [],
            'actions': [],
            'initial_sort': [],
            'table_id': 'documents_table',
            'form_action': url_for('document_bp.handle_document_selection'),
            'description': 'An error occurred while retrieving the documents. Please try again later.'
        }