
from app import AuditLogger
from app.models import Systems
from app.extensions.db import db
from flask_login import current_user
from sqlalchemy import asc, desc

auditlog = AuditLogger(db.session)

class SystemService:
    def __init__(self):
        self.auditlog = auditlog


    def get_systems(self, page=1, per_page=10, sort_field='system_id', sort_order='asc'):
        """

        :param page:
        :param per_page:
        :param sort_field:
        :param sort_order:
        :return:
        """
        sort_func = asc if sort_order == 'asc' else desc
        sort_attr = getattr(Systems, sort_field, Systems.system_id)

        if sort_field == 'system_id':
            query = Systems.query.order_by(sort_func(Systems.system_id.cast(db.Integer)))
        else:
            query = Systems.query.order_by(sort_func(sort_attr))

        systems_query = query.paginate(page=page, per_page=per_page, error_out=False)

        return {
            'systems': [{
                'system_id': s.system_id,
                'system_name': s.system_name,
                'name': s.name,
            } for s in systems_query.items],
            'total_systems': systems_query.total,
            'total_pages': systems_query.pages,
            'current_page': systems_query.page,
            'per_page': systems_query.per_page
        }

    def get_system_by_id(self, system_id):
        """

        :param system_id:
        :return:
        """
        return Systems.query.filter_by(system_id=system_id).first()

    def add_system(self, data):
        """

        :param data:
        :return:
        """
        system_id = data.get('system_id')
        system_name = data.get('system_name')
        name = data.get('name')
        error = None

        if not system_id.isdigit():
            error = 'ID системы должен содержать только числа.'
            status = 400
        elif Systems.query.get(system_id):
            error = 'Система с таким ID уже существует'
            status = 409
        else:
            try:
                system = Systems(system_id=system_id, system_name=system_name, name=name)
                db.session.add(system)
                db.session.commit()
                status = 201
            except Exception as e:
                db.session.rollback()
                error = str(e)
                status = 500

        self.auditlog.systems(
            action_type="add",
            actor_display_name=current_user.display_name,
            ldap_user_id=current_user.id,
            system_id=system_id,
            name=f'{system_name}; ({name})',
            error=error
        )

        return {'status': 'error' if error else 'success', 'message': error or 'Система добавлена'}, status

    def update_system_name(self, data):
        system_id = data.get('system_id')
        system_name = data.get('system_name')
        name = data.get('name')
        error = None

        if system_id is None:
            return {'status': 'error', 'message': 'system_id обязателен'}, 400
        if system_name is None or name is None:
            return {'status': 'error', 'message': 'Поля system_name и name обязательны'}, 400

        try:
            system = Systems.query.get(system_id)
            if system:
                old_name = system.name  # Старое имя
                system.system_name = system_name
                system.name = name
                db.session.commit()
                status = 200
            else:
                error = 'Система не найдена'
                status = 404
        except Exception as e:
            db.session.rollback()
            error = str(e)
            status = 500

        # Формируем отображение вида "старое_имя → новое_имя"
        if not error and system:
            log_name = f"{old_name} → {name}"
        else:
            log_name = name  # Если ошибка, логируем только новое имя

        self.auditlog.systems(
            action_type="update",
            actor_display_name=current_user.display_name,
            ldap_user_id=current_user.id,
            system_id=system_id,
            name=log_name,
            error=error
        )

        return {'status': 'error' if error else 'success', 'message': error or 'Название системы изменено'}, status




    def delete_system(self, system_id):
        """

        :param system_id:
        :return:
        """
        error = None
        system = Systems.query.get(system_id)

        if not system:
            error = 'Система не найдена'
            status = 404
        else:
            try:
                db.session.delete(system)
                db.session.commit()
                status = 200
            except Exception as e:
                db.session.rollback()
                error = str(e)
                status = 500

        self.auditlog.systems(
            action_type="delete",
            actor_display_name=current_user.display_name,
            ldap_user_id=current_user.id,
            system_id=system_id,
            name=f'{system.system_name}; ({system.name})' if system else None,
            error=error
        )

        return {'status': 'error' if error else 'success', 'message': error or 'Система удалена'}, status
