import logging

from apps.companies.constants import CompanyType
from apps.permissions.models import Permission, Role
from apps.companies.repositories import CompanyRoleRepository


logger = logging.getLogger(__name__)


class CompanyRoleService:
    """Service for managing company roles and permissions"""

    DEALERSHIP_ROLE = {
            'name': 'Dealership Admin',
            'description': (
                'This role is specifically created for dealership admin '
                'which is a dealership under a parent dealerships groups.'
            ),
            'permissions': [
                'dealership_group_view_calls',
                'dealership_group_view_dashboard',
            ]
    }

    DEALERSHIP_GROUP_ROLE = {
            'name': 'Dealerships Group Admin',
            'description': (
                'This role is specifically created for dealership groups '
                'where a head office have hierarchy of other dealerships and groups.'
            ),
            'permissions': [
                'dealership_group_create_dealerships',
                'dealership_group_create_departments',
                'dealership_group_edit_departments',
                'dealership_group_view_calls',
                'dealership_group_view_dashboard',
                'dealership_group_view_dealerships',
                'dealership_group_view_departments',
                'edit_company',
                'view_company_bots',
                'edit_company_bots',
                'view_dealerships_admins', 'create_dealerships_admins',
                'delete_dealerships_admins'
                'view_officehours', 'edit_officehours', 'edit_holidays',
                'manage_rabeeca_settings','view_holidays',
                'view_profile', 'view_other_profiles',
            ]
    }

    DEFAULT_ROLES = [
        {
            'name': 'Chief Admin',
            'description': 'Company administrator with full permissions',
            'permissions': [
                'view_roles', 'create_roles', 'edit_roles', 'delete_roles', 'view_customers',
                'view_users', 'create_users', 'edit_users', 'delete_users', 'manage_users',
                'view_company', 'edit_company', 'delete_company',
                'view_reports', 'view_analytics', 'view_profile', 'edit_profile',
                'view_other_profiles', 'view_permissions', 'assign_roles', 'view_bdc_dashboard',
                'view_service_dashboard', 'view_holidays', 'edit_holidays', 'view_company_bots',
                'edit_company_bots',
                'view_service_calls',
                'view_officehours', 'edit_officehours', 'view_salestime', 'edit_salestime', 'view_catchphrase',
                'edit_catchphrase',
                'view_calendar', 'update_password', 'view_bdc_calls', 'view_audit_log', 'manage_hazel_settings', 'manage_maya_settings',
            ]
        },
        {
            'name': 'BDC Manager',
            'description': 'BDC Manager with user and company management access',
            'permissions': [
                'view_users', 'view_bdc_dashboard', 'update_password',
                'view_bdc_calls',
            ]
        },
        {
            'name': 'Service Manager',
            'description': 'Basic employee with limited access',
            'permissions': [
                'view_users', 'view_service_dashboard',
                'view_service_calls', 'view_customers',
                'view_reports', 'update_password', 'view_audit_log',
            ]
        },
        {
            'name': 'BDC Advisor',
            'description': 'Read-only access to company data',
            'permissions': [
                'view_bdc_dashboard', 'view_officehours', 'view_bdc_calls',
            ]
        },
        {
            'name': 'Service Advisor',
            'description': 'Read-only access to company data',
            'permissions': [
                'view_advisor_dashboard', 'view_officehours', 'view_self_service_calls',
            ]
        }
    ]

    @staticmethod
    def create_default_roles(company):
        """Create default roles for a company when it's first created"""

        if company.company_type == CompanyType.DEALERSHIP:
            CompanyRoleService._create_default_role_internal(
                CompanyRoleService.DEALERSHIP_ROLE,
                company,
            )
            return

        if company.company_type == CompanyType.DEALERSHIP_GROUP:
            CompanyRoleService._create_default_role_internal(
                CompanyRoleService.DEALERSHIP_GROUP_ROLE,
                company,
            )
            return

        for role_data in CompanyRoleService.DEFAULT_ROLES:
            CompanyRoleService._create_default_role_internal(role_data, company)

    @staticmethod
    def _create_default_role_internal(default_role, company):
            try:
                requested_perms = default_role['permissions']

                permissions = Permission.objects.filter(
                    codename__in=requested_perms,
                    is_active=True
                )

                missing = set(requested_perms) - set(permissions.values_list('codename', flat=True))
                if missing:
                    logger.warning(
                        f'Missing permissions for role"{default_role["name"]}": {missing}'
                    )

                # Use get_or_create to prevent duplicates
                role, created = Role.objects.get_or_create(
                    name=default_role['name'],
                    company=company,
                    defaults={
                        'description': default_role['description'],
                        'is_active': True
                    }
                )

                if created:
                    role.permissions.set(permissions)
                    logger.info(f"Created role '{role.name}' for company '{company.name}'")
                else:
                    logger.info(f"Role '{role.name}' already exists for company '{company.name}'")

            except Exception as e:
                logger.error(
                    f"Failed to create role '{default_role['name']}' "
                    f"for company '{company.name}': {str(e)}"
                )

    @staticmethod
    def list_roles_for_company(user):
        company = getattr(user, 'active_company', None)
        if not company:
            return []

        role_names = CompanyRoleRepository.list_company_roles(company)

        response = []
        for idx, name in enumerate(role_names, start=1):
            response.append({
                "id": idx,
                "key": name.lower().replace(' ', '_'),
                "label": name,
            })

        return response

    @staticmethod
    def map_param_to_role_names(param_list, user):
        """Convert frontend role filters (ids, keys, labels) to actual company role names."""
        company = getattr(user, 'active_company', None)
        if not company:
            return []

        # Normalize frontend input
        normalized = [str(p).strip().lower().replace(' ', '_') for p in param_list]

        # Get all active company roles
        roles = company.roles.filter(is_active=True)
        role_map = {}
        for role in roles:
            key = role.name.lower().replace(' ', '_')
            role_map[str(role.id)] = role.name.lower()      # ID -> name
            role_map[key] = role.name.lower()              # key -> name
            role_map[role.name.lower()] = role.name.lower() # label -> name

        # Only keep roles that match
        role_names = []
        for val in normalized:
            if val in role_map:
                role_names.append(role_map[val])

        return list(set(role_names))  # remove duplicates
