from flask import redirect, flash, current_app, session, url_for
from flask_security import roles_accepted
from sqlalchemy.exc import SQLAlchemyError
import ast

from common.models.user import Tenant, User, TenantDomain, TenantProject, TenantMake, PartnerTenant, PartnerService, \
    ConsentVersion, TenantConsent, Partner
from common.services.user import UserServices, PartnerServices
from common.utils.eveai_exceptions import EveAINoSessionPartner, EveAINoManagementPartnerService
from common.utils.security_utils import current_user_has_role
from eveai_app.views.list_views.list_view_utils import render_list_view
from common.extensions import db

# Tenant list view helper
def get_tenants_list_view():
    """Generate the tenants list view configuration"""
    # Get all tenants (no server side filtering - handled client-side)
    is_partner_admin = current_user_has_role('Partner Admin')
    is_super_user = current_user_has_role('Super User')

    if is_partner_admin and not is_super_user:
        # Partner Admin (not Super User) - filter tenants based on management service + own tenant
        try:
            partner = session.get('partner')
            if not partner:
                # No partner in session, return empty list
                all_tenants = []
            else:
                tenant_ids = set()

                # Add the partner's own tenant
                partner_tenant_id = partner.get('tenant_id')
                if partner_tenant_id:
                    tenant_ids.add(partner_tenant_id)

                # Add tenants associated with the management service
                management_service = PartnerServices.get_management_service()
                if management_service:
                    management_service_id = management_service['id']
                    # Get tenant IDs associated with this management service via PartnerTenant
                    partner_tenants = PartnerTenant.query.filter_by(
                        partner_service_id=management_service_id
                    ).all()
                    for pt in partner_tenants:
                        tenant_ids.add(pt.tenant_id)

                # Query for all allowed tenants
                if tenant_ids:
                    tenant_query = Tenant.query.filter(Tenant.id.in_(tenant_ids)).order_by(Tenant.id)
                    all_tenants = tenant_query.all()
                else:
                    all_tenants = []

        except (EveAINoSessionPartner, EveAINoManagementPartnerService):
            # No partner in session or no management service
            # Still try to get the partner's own tenant if available
            try:
                partner = session.get('partner')
                if partner and partner.get('tenant_id'):
                    tenant_query = Tenant.query.filter_by(id=partner['tenant_id']).order_by(Tenant.id)
                    all_tenants = tenant_query.all()
                else:
                    all_tenants = []
            except Exception:
                all_tenants = []
    else:
        # Super User or other roles - get all tenants
        tenant_query = Tenant.query.order_by(Tenant.id)
        all_tenants = tenant_query.all()

    # Prepare data for Tabulator
    data = []
    for tenant in all_tenants:
        data.append({
            'id': tenant.id,
            'name': tenant.name,
            'type': tenant.type
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'Type', 'field': 'type'},
    ]

    actions = [
        {'value': 'select_tenant', 'text': 'Set Session Tenant', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'edit_tenant', 'text': 'Edit tenant', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_tenant', 'text': 'Register tenant', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Tenants',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenants_table',
        'form_action': url_for('user_bp.handle_tenant_selection'),
        'description': 'View and manage tenants'
    }


# Users list view helper
def get_users_list_view(tenant_id):
    """Generate the users list view configuration for a specific tenant"""
    # Get users for the tenant
    query = User.query.filter_by(tenant_id=tenant_id).order_by(User.user_name)
    users = query.all()

    # Prepare data for Tabulator
    data = []
    for user in users:
        data.append({
            'id': user.id,
            'user_name': user.user_name,
            'email': user.email,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'active': user.active
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'User Name', 'field': 'user_name'},
        {'title': 'Email', 'field': 'email'},
        {'title': 'First Name', 'field': 'first_name'},
        {'title': 'Last Name', 'field': 'last_name'},
        {'title': 'Active', 'field': 'active', 'formatter': 'tickCross'}
    ]

    actions = [
        {'value': 'edit_user', 'text': 'Edit User', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'resend_confirmation_email', 'text': 'Resend Confirmation', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'send_password_reset_email', 'text': 'Send Password Reset', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'reset_uniquifier', 'text': 'Reset Uniquifier', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'create_user', 'text': 'Register User', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Users',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'users_table',
        'form_action': url_for('user_bp.handle_user_action'),
        'description': f'Users for tenant {tenant_id}'
    }


# Tenant Domains list view helper
def get_tenant_domains_list_view(tenant_id):
    """Generate the tenant domains list view configuration for a specific tenant"""
    # Get domains for the tenant
    query = TenantDomain.query.filter_by(tenant_id=tenant_id).order_by(TenantDomain.domain)
    domains = query.all()

    # Prepare data for Tabulator
    data = []
    for domain in domains:
        data.append({
            'id': domain.id,
            'domain': domain.domain,
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Domain', 'field': 'domain'},
    ]

    actions = [
        {'value': 'edit_tenant_domain', 'text': 'Edit Domain', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_tenant_domain', 'text': 'Register Domain', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Domains',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenant_domains_table',
        'form_action': url_for('user_bp.handle_tenant_domain_action'),
        'description': f'Domains for tenant {tenant_id}'
    }


# Tenant Projects list view helper
def get_tenant_projects_list_view(tenant_id):
    """Generate the tenant projects list view configuration for a specific tenant"""
    # Get projects for the tenant
    query = TenantProject.query.filter_by(tenant_id=tenant_id).order_by(TenantProject.id)
    projects = query.all()

    # Prepare data for Tabulator
    data = []
    for project in projects:
        data.append({
            'id': project.id,
            'name': project.name,
            'visual_api_key': project.visual_api_key,
            'responsible_email': project.responsible_email,
            'active': project.active
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'API Key', 'field': 'visual_api_key'},
        {'title': 'Responsible', 'field': 'responsible_email'},
        {'title': 'Active', 'field': 'active', 'formatter': 'tickCross'}
    ]

    actions = [
        {'value': 'edit_tenant_project', 'text': 'Edit Project', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'invalidate_tenant_project', 'text': 'Invalidate Project', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'delete_tenant_project', 'text': 'Delete Project', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'create_tenant_project', 'text': 'Register Project', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Projects',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenant_projects_table',
        'form_action': url_for('user_bp.handle_tenant_project_selection'),
        'description': f'Projects for tenant {tenant_id}'
    }


# Tenant Makes list view helper
def get_tenant_makes_list_view(tenant_id):
    """Generate the tenant makes list view configuration for a specific tenant"""
    # Get makes for the tenant
    query = TenantMake.query.filter_by(tenant_id=tenant_id).order_by(TenantMake.id)
    makes = query.all()

    # Prepare data for Tabulator
    data = []
    for make in makes:
        data.append({
            'id': make.id,
            'name': make.name,
            'website': make.website,
            'active': make.active
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'Website', 'field': 'website'},
        {'title': 'Active', 'field': 'active', 'formatter': 'tickCross'}
    ]

    actions = [
        {'value': 'edit_tenant_make', 'text': 'Edit Make', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'set_as_default', 'text': 'Set as Default', 'class': 'btn-secondary', 'requiresSelection': True},
        {'value': 'create_tenant_make', 'text': 'Create Make', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Makes',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenant_makes_table',
        'form_action': url_for('user_bp.handle_tenant_make_selection'),
        'description': f'Makes for tenant {tenant_id}'
    }


    # Tenant Partner Services list view helper


def get_tenant_partner_services_list_view(tenant_id):
    """Generate the tenant partner services list view configuration for a specific tenant"""
    # Get partner services for the tenant through PartnerTenant association
    query = PartnerService.query.join(PartnerTenant).filter(PartnerTenant.tenant_id == tenant_id)
    partner_services = query.all()

    # Prepare data for Tabulator
    data = []
    for service in partner_services:
        data.append({
            'id': service.id,
            'name': service.name,
            'type': service.type,
            'type_version': service.type_version,
            'active': service.active
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Name', 'field': 'name'},
        {'title': 'Type', 'field': 'type'},
        {'title': 'Version', 'field': 'type_version'},
        {'title': 'Active', 'field': 'active', 'formatter': 'tickCross', 'width': 120}
    ]

    # No actions needed as specified in requirements
    actions = []

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

    return {
        'title': 'Partner Services',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenant_partner_services_table',
        'form_action': url_for('user_bp.tenant_partner_services'),
        'description': f'Partner Services for tenant {tenant_id}'
    }


def get_consent_versions_list_view():
    """Generate the tenant makes list view configuration for a specific tenant"""
    # Get makes for the tenant
    query = ConsentVersion.query.filter_by().order_by(ConsentVersion.id)
    consent_versions = query.all()

    # Prepare data for Tabulator
    data = []
    for cv in consent_versions:
        data.append({
            'id': cv.id,
            'consent_type': cv.consent_type,
            'consent_version': cv.consent_version,
            'consent_valid_from': cv.consent_valid_from.strftime('%Y-%m-%d') if cv.consent_valid_from else '',
            'consent_valid_to': cv.consent_valid_to.strftime('%Y-%m-%d') if cv.consent_valid_to else '',
        })

    # Column Definitions
    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Consent Type', 'field': 'consent_type'},
        {'title': 'From', 'field': 'consent_valid_from'},
        {'title': 'To', 'field': 'consent_valid_to'}
    ]

    actions = [
        {'value': 'edit_consent_version', 'text': 'Edit Consent Version', 'class': 'btn-primary', 'requiresSelection': True},
        {'value': 'create_consent_version', 'text': 'Create Consent Version', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False},
    ]

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

    return {
        'title': 'Consent Versions',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'consent_versions_table',
        'form_action': url_for('user_bp.handle_consent_version_selection'),
        'description': f'Consent Versions'
    }



# Tenant Consents history list view helper

def get_tenant_consents_list_view(tenant_id):
    """Generate the tenant consents history list view configuration for a specific tenant"""
    # Build query joining optional partner->tenant for partner name and user for user name
    q = db.session.query(
        TenantConsent.id,
        TenantConsent.consent_type,
        TenantConsent.consent_date,
        TenantConsent.consent_version,
        User.user_name.label('user_name'),
        Tenant.name.label('partner_name')
    ).join(User, User.id == TenantConsent.user_id)
    # Left join Partner and its Tenant to get the partner tenant name
    q = q.outerjoin(Partner, Partner.id == TenantConsent.partner_id)
    q = q.outerjoin(Tenant, Tenant.id == Partner.tenant_id)
    q = q.filter(TenantConsent.tenant_id == tenant_id).order_by(TenantConsent.consent_date.desc())

    rows = q.all()

    data = []
    for r in rows:
        partner_name = r.partner_name if r.partner_name else '-'
        data.append({
            'id': r.id,
            'consent_type': r.consent_type,
            'consent_date': r.consent_date.isoformat() if hasattr(r.consent_date, 'isoformat') else str(r.consent_date),
            'consent_version': r.consent_version,
            'user_name': r.user_name,
            'partner_name': partner_name,
        })

    columns = [
        {'title': 'ID', 'field': 'id', 'width': 80},
        {'title': 'Type', 'field': 'consent_type'},
        {'title': 'Date', 'field': 'consent_date'},
        {'title': 'Version', 'field': 'consent_version'},
        {'title': 'User', 'field': 'user_name'},
        {'title': 'Partner', 'field': 'partner_name'},
    ]

    # Only a view action as records are immutable; handled via a POST -> redirect in the view handler
    actions = [
        {'value': 'view_consent_document', 'text': 'Bekijk document', 'class': 'btn-outline-secondary', 'requiresSelection': True},
    ]

    initial_sort = [{'column': 'consent_date', 'dir': 'desc'}]

    return {
        'title': 'Tenant Consents History',
        'data': data,
        'columns': columns,
        'actions': actions,
        'initial_sort': initial_sort,
        'table_id': 'tenant_consents_history_table',
        'form_action': url_for('user_bp.handle_tenant_consents_history_selection'),
        'description': f'Consent history for tenant {tenant_id}'
    }
