#import concurrent
import requests
from .internal_event_ops import InternalEventOperations
from models.event_notification import EventNotification
from models.access_control_policy_list_ext import AccessControlPolicyListExt
from models.capif_event_detail import CAPIFEventDetail
from models.event_subscription import EventSubscription
from models.service_api_description import ServiceAPIDescription
from encoder import CustomJSONEncoder
import sys
import json
from flask import current_app
import asyncio
import aiohttp
from util import dict_to_camel_case, clean_empty, serialize_clean_camel_case

class Notifications():

    def __init__(self):
        self.events_ops = InternalEventOperations()

    def send_notifications(self, redis_event):
        try:
            if redis_event.get('event', None) == None:
                raise("Event value is not present on received event from REDIS")
            
            current_app.logger.info("Received event " + redis_event.get('event') + ", sending notifications")
            subscriptions = self.events_ops.get_event_subscriptions(redis_event.get('event'))
            current_app.logger.info(subscriptions)

            for sub in subscriptions:
                url = sub["notification_destination"]
                current_app.logger.debug(url)
                data = EventNotification(sub["subscription_id"], events=redis_event.get('event'))
                if redis_event.get('key', None) != None and redis_event.get('information', None) != None:
                    event_detail={}
                    for pos, key in enumerate(redis_event.get('key', None)):

                        if sub["supported_features"] is None:
                            if not (key == "serviceAPIDescriptions" and redis_event.get('event', None) in ["SERVICE_API_AVAILABLE", "SERVICE_API_UNAVAILABLE"]):
                                event_detail[key]=redis_event.get('information', None)[pos]
                        else:
                            if not (redis_event.get('event', None) in ["SERVICE_API_AVAILABLE", "SERVICE_API_UNAVAILABLE"] and key == "serviceAPIDescriptions" and not EventSubscription.return_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]):
                                event_detail[key]=redis_event.get('information', None)[pos]

                    current_app.logger.debug(event_detail)
                    data.event_detail=event_detail

                current_app.logger.debug(json.dumps(data.to_dict(),cls=CustomJSONEncoder))

                asyncio.run(self.send(url, serialize_clean_camel_case(data)))

        except Exception as e:
            current_app.logger.error("An exception occurred ::" + str(e))
            return False

    def request_post(self, url, data):
        headers = {'content-type': 'application/json'}
        return requests.post(url, json={'text': str(data.to_str())}, headers=headers)
    
    async def send_request(self, url, data):
        async with aiohttp.ClientSession() as session:
            timeout = aiohttp.ClientTimeout(total=10)  # Establecer timeout a 10 segundos
            headers = {'content-type': 'application/json'}
            async with session.post(url, json=data, timeout=timeout, headers=headers) as response:
                return await response.text()
    
    async def send(self, url, data):
        try:
            response = await self.send_request(url, data)
            current_app.logger.debug(response)
        except asyncio.TimeoutError:
            current_app.logger.error("Timeout: Request timeout")
        except Exception as e:
            current_app.logger.error("An exception occurred sending notification::" + str(e))
            return False
