#import concurrent
import asyncio
import json
import os

import aiohttp
import requests
from encoder import CustomJSONEncoder
from flask import current_app
from models.event_notification import EventNotification
from models.event_subscription import EventSubscription
from util import serialize_clean_camel_case

from .internal_event_ops import InternalEventOperations


class Notifications():

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

    def send_notifications(self, redis_event):
        try:
            event = redis_event.get('event', None)
            if event is None:
                raise("Event value is not present on received event from REDIS")
            

            current_app.logger.info("Received event " + event + ", sending notifications")
            subscriptions = self.events_ops.get_event_subscriptions(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=event)
                event_detail_redis=redis_event.get('event_detail', None)
                if event_detail_redis is not None:
                    if EventSubscription.return_supp_feat_dict(sub["supported_features"])["EnhancedEventReport"]:
                        event_detail={}
                        current_app.logger.debug(f"event: {event_detail_redis}")
                        if event in ["SERVICE_API_AVAILABLE", "SERVICE_API_UNAVAILABLE"]:
                            event_detail["apiIds"]=event_detail_redis.get('apiIds', None)
                            if EventSubscription.return_supp_feat_dict(sub["supported_features"])["ApiStatusMonitoring"]:
                                event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                        elif event in ["SERVICE_API_UPDATE"]:
                            event_detail["serviceAPIDescriptions"]=event_detail_redis.get('serviceAPIDescriptions', None)
                        elif event in ["API_INVOKER_ONBOARDED", "API_INVOKER_OFFBOARDED", "API_INVOKER_UPDATED"]:
                            event_detail["apiInvokerIds"]=event_detail_redis.get('apiInvokerIds', None)
                        elif event in ["ACCESS_CONTROL_POLICY_UPDATE"]:
                            event_detail["accCtrlPolList"]=event_detail_redis.get('accCtrlPolList', None)
                        elif event in ["SERVICE_API_INVOCATION_SUCCESS", "SERVICE_API_INVOCATION_FAILURE"]:
                            event_detail["invocationLogs"]=event_detail_redis.get('invocationLogs', None)
                        elif event in ["API_TOPOLOGY_HIDING_CREATED", "API_TOPOLOGY_HIDING_REVOKED"]:
                            event_detail["apiTopoHide"]=event_detail_redis.get('apiTopoHide', None)

                        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, timeout=os.getenv("TIMEOUT"))
    
    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
