from flask import current_app
from sqlalchemy import desc, asc
import logging
from app import Regions, db, Users, Subscriptions
from app.extensions.audit_logger import AuditLogger


auditlog = AuditLogger(db.session)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

class RegionService:
    def __init__(self):
        self.db = db
        self.auditlog = auditlog
        self.logger = logger

    def get_regions(self, page=1, per_page=10, sort_field='region_id', sort_order='asc'):
        self.logger.info(f"Получение регионов: page={page}, per_page={per_page}, sort_field={sort_field}, sort_order={sort_order}")

        # Определение порядка сортировки
        sort_func = asc if sort_order == 'asc' else desc

        # Получение атрибута модели для сортировки
        if sort_field:
            sort_attr = getattr(Regions, sort_field, Regions.region_id)  # По умолчанию сортируем по region_id
        else:
            sort_attr = Regions.region_id

        # Запрос к базе данных с учетом сортировки и пагинации
        if sort_field == 'region_id':
            regions_query = Regions.query.order_by(sort_func(Regions.region_id.cast(db.Integer))).paginate(page=page, per_page=per_page, error_out=False)
        elif sort_field == 'name':
            regions_query = Regions.query.order_by(sort_func(Regions.region_name)).paginate(page=page, per_page=per_page, error_out=False)
        else:
            regions_query = Regions.query.order_by(sort_func(sort_attr)).paginate(page=page, per_page=per_page, error_out=False)

        regions_list = [{
            'region_id': r.region_id,
            'name': r.region_name,
            'active': r.active
        } for r in regions_query.items]

        # bf.app.logger.info(f"Получены регионы: {len(regions_list)} элементов")

        return {
            'regions': regions_list,
            'total_regions': regions_query.total,
            'total_pages': regions_query.pages,
            'current_page': regions_query.page,
            'per_page': regions_query.per_page
        }

    def get_region_by_id(self, region_id):
        # bf.app.logger.info(f"Поиск региона по ID: {region_id}")

        # Получение региона по его ID
        region = Regions.query.filter_by(region_id=region_id).first()

        if region:
            # bf.app.logger.info(f"Найден регион: {region.region_name}")
            return region.region_name
        else:
            # bf.app.logger.warning(f"Регион с ID {region_id} не найден.")
            return None

    def get_region_subscribers(self, region_id):
        # bf.app.logger.info(f"Получение подписчиков региона: region_id={region_id}")

        try:
            region = Regions.query.get(region_id)
            if not region:
                # bf.app.logger.warning(f"Регион с ID {region_id} не найден")
                return {'status': 'error', 'message': 'Регион не найден'}, 404

            subscribers = self.db.session.query(
                Users).join(Subscriptions).filter(Subscriptions.region_id == region_id).all()

            subscribers_list = [{
                'chat_id': user.chat_id,
                'telegram_id': user.telegram_id,
                'email': user.user_email
            } for user in subscribers]

            # bf.app.logger.info(f"Получены подписчики региона {region_id}: {len(subscribers_list)} элементов")

            return {'status': 'success', 'subscribers': subscribers_list}, 200
        except Exception as e:
            # bf.app.logger.error(f"Ошибка при получении подписчиков региона: {e}")
            return {'status': 'error', 'message': str(e)}, 500

    def add_region(self, data, user):
        region_id = data.get('region_id')
        name = data.get('name')
        active = data.get('active', True)

        self.logger.info(f"Добавление региона: region_id={region_id}, name={name}, active={active}")

        try:
            if not region_id.isdigit():
                self.logger.warning(f"ID региона {region_id} содержит нечисловые символы")
                error_msg = 'ID региона должен содержать только числа.'
                self.auditlog.regions(
                    action_type="add",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    name=name,
                    region_id=region_id,
                    error=error_msg
                )
                return {'status': 'error', 'message': error_msg}, 400

            existing_region = Regions.query.get(region_id)
            if existing_region:
                self.logger.warning(f"Регион с ID {region_id} уже существует")
                error_msg = 'Регион с таким ID уже существует'
                self.auditlog.regions(
                    action_type="add",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    name=name,
                    region_id=region_id,
                    error=error_msg
                )
                return {'status': 'error', 'message': error_msg}, 409

            region = Regions(region_id=region_id, region_name=name, active=active)
            self.db.session.add(region)
            self.db.session.commit()

            self.logger.info(f"Регион {region_id} успешно добавлен")
            self.auditlog.regions(
                action_type="add",
                actor_display_name=user.display_name,
                ldap_user_id=user.id,
                name=name,
                region_id=region_id
            )
            return {'status': 'success', 'message': 'Регион добавлен'}, 201

        except Exception as e:
            self.db.session.rollback()
            error_msg = str(e)
            self.logger.error(f"Ошибка при добавлении региона: {error_msg}")
            self.auditlog.regions(
                action_type="add",
                actor_display_name=user.display_name,
                ldap_user_id=user.id,
                name=name,
                region_id=region_id,
                error=error_msg
            )
            return {'status': 'error', 'message': error_msg}, 500

    def update_region_status(self, data, user):
        region_id = data.get('region_id')
        new_status = data.get('active')

        self.logger.info(f"Изменение статуса региона: region_id={region_id}, new_status={new_status}")

        try:
            region = Regions.query.get(region_id)
            if region:
                old_status = region.active
                region.active = new_status
                self.db.session.commit()

                self.logger.info(f"Статус региона {region_id} изменён: {old_status} → {new_status}")
                self.auditlog.regions(
                    action_type="toggle",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    old_active=old_status,
                    active=new_status
                )

                return {'status': 'success', 'message': 'Статус региона обновлён'}, 200
            else:
                error_msg = f"Регион с ID {region_id} не найден"
                self.logger.warning(error_msg)
                self.auditlog.regions(
                    action_type="toggle",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    active=new_status,
                    error=error_msg
                )
                return {'status': 'error', 'message': 'Регион не найден'}, 404
        except Exception as e:
            self.db.session.rollback()
            error_msg = str(e)
            self.logger.error(f"Ошибка при изменении статуса региона: {error_msg}")
            self.auditlog.regions(
                action_type="toggle",
                actor_display_name=user.display_name,
                ldap_user_id=user.id,
                region_id=region_id,
                active=new_status,
                error=error_msg
            )
            return {'status': 'error', 'message': error_msg}, 500



    def update_region_name(self, data, user):
        region_id = data.get('region_id')
        name = data.get('name')

        self.logger.info(f"Изменение названия региона: region_id={region_id}, name={name}")

        try:
            region = Regions.query.get(region_id)
            if region:
                old_name = region.region_name
                region.region_name = name
                self.db.session.commit()

                self.logger.info(f"Название региона {region_id} изменено с {old_name} на {name}")
                self.auditlog.regions(
                    action_type="rename",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    new_name=name,
                    old_name=old_name
                )

                return {'status': 'success', 'message': 'Название региона изменено'}, 200
            else:
                error_msg = f"Регион с ID {region_id} не найден"
                self.logger.warning(error_msg)
                self.auditlog.regions(
                    action_type="rename",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    new_name=name,
                    error=error_msg
                )
                return {'status': 'error', 'message': 'Регион не найден'}, 404
        except Exception as e:
            self.db.session.rollback()
            error_msg = str(e)
            self.logger.error(f"Ошибка при изменении названия региона: {error_msg}")
            self.auditlog.regions(
                action_type="rename",
                actor_display_name=user.display_name,
                ldap_user_id=user.id,
                region_id=region_id,
                new_name=name,
                error=error_msg
            )
            return {'status': 'error', 'message': error_msg}, 500

    def delete_region(self, region_id, user):
        self.logger.info(f"Удаление региона: region_id={region_id}")

        try:
            region = Regions.query.get(region_id)
            if region:
                name = region.region_name
                self.db.session.delete(region)
                self.db.session.commit()

                self.logger.info(f"Регион {region_id} успешно удалён")
                self.auditlog.regions(
                    action_type="delete",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    new_name=name
                )

                return {'status': 'success', 'message': 'Регион удалён'}, 200
            else:
                error_msg = f"Регион с ID {region_id} не найден"
                self.logger.warning(error_msg)
                self.auditlog.regions(
                    action_type="delete",
                    actor_display_name=user.display_name,
                    ldap_user_id=user.id,
                    region_id=region_id,
                    error=error_msg
                )
                return {'status': 'error', 'message': 'Регион не найден'}, 404
        except Exception as e:
            self.db.session.rollback()
            error_msg = str(e)
            self.logger.error(f"Ошибка при удалении региона: {error_msg}")
            self.auditlog.regions(
                action_type="delete",
                actor_display_name=user.display_name,
                ldap_user_id=user.id,
                region_id=region_id,
                error=error_msg
            )
            return {'status': 'error', 'message': error_msg}, 500
