from flask import session, flash, current_app
from datetime import datetime as dt, timezone as tz

from sqlalchemy.exc import SQLAlchemyError

from common.extensions import db
from common.models.entitlements import PartnerServiceLicenseTier
from common.models.user import Partner
from common.utils.eveai_exceptions import EveAINoManagementPartnerService, EveAINoSessionPartner
from common.utils.model_logging_utils import set_logging_information


class LicenseTierServices:
    @staticmethod
    def associate_license_tier_with_partner(license_tier_id):
        """Associate a license tier with a partner"""
        try:
            partner_id = session['partner']['id']
            # Get partner service (MANAGEMENT_SERVICE type)
            partner = Partner.query.get(partner_id)
            if not partner:
                raise EveAINoSessionPartner()

            # Find a management service for this partner
            management_service = next((service for service in session['partner']['services']
                                       if service.get('type') == 'MANAGEMENT_SERVICE'), None)

            if not management_service:
                flash("Cannot associate license tier with partner. No management service defined for partner", "danger")
                current_app.logger.error(f"No Management Service defined for partner {partner_id}"
                                         f"trying to associate license tier {license_tier_id}.")
                raise EveAINoManagementPartnerService()
            # Check if the association already exists
            existing_association = PartnerServiceLicenseTier.query.filter_by(
                partner_service_id=management_service['id'],
                license_tier_id=license_tier_id
            ).first()

            if existing_association:
                # Association already exists, nothing to do
                flash("License tier was already associated with partner", "info")
                current_app.logger.info(f"Association between partner service {management_service['id']} and "
                                        f"license tier {license_tier_id} already exists.")
                return

            # Create the association
            association = PartnerServiceLicenseTier(
                partner_service_id=management_service['id'],
                license_tier_id=license_tier_id
            )
            set_logging_information(association, dt.now(tz.utc))

            db.session.add(association)
            db.session.commit()

            flash("Successfully associated license tier to partner", "success")
            current_app.logger.info(f"Successfully associated license tier {license_tier_id} with "
                                    f"partner service {management_service['id']}")

            return True

        except SQLAlchemyError as e:
            db.session.rollback()
            flash("Failed to associated license tier with partner service due to an internal error. "
                  "Please contact the System Administrator", "danger")
            current_app.logger.error(f"Error associating license tier {license_tier_id} with partner: {str(e)}")
            raise e
