import cv2
import time
import base64
import os
from uuid import uuid1
from datetime import datetime
from cachetools import cached, TTLCache
from edge_engine.common.logsetup import logger

from scripts.common.config import MONGO_DB_OBJ, APP_MONGO_COLLECTION

TTL = 5


class InfoCenter:
    def __init__(self, device_id):
        self.device_id = device_id
        self.attendance_event_collection = MONGO_DB_OBJ[APP_MONGO_COLLECTION.get('eventLogCollection')]
        self.camera_configuration = MONGO_DB_OBJ[APP_MONGO_COLLECTION.get('cameraConfigurationCollection')]
        self.camera_mapping_json = self.get_all_cameras()
        self.ttl_check = NotificationFilter()
        self.camera_key = os.environ.get('app',None)

    def get_all_cameras(self):
        camera_mapping_json = self.camera_configuration.find({'decommissioned': False}, {"_id": 0})
        camera_json = {}
        for each in camera_mapping_json:
            camera_json[each['cameraId']] = each['cameraName']
        return camera_json

    def send_payload(self,
                     frame,
                     label='person_monitoring',
                     bg_color="#474520",
                     font_color="#FFFF00",
                     alert_sound=None,
                     message="",
                     person_count=0):
        if self.ttl_check.check_rpt(str(person_count)):
            frame = cv2.resize(frame, (64, 64))
            payload = {"deviceId": self.device_id,
                       "message": message,
                       "frame": 'data:image/jpeg;base64,' + base64.b64encode(
                           cv2.imencode('.jpg', frame)[1].tostring()).decode("utf-8"),
                       "activity": label,
                       "bg_color": bg_color,
                       "font_color": font_color,
                       "alert_sound": alert_sound,
                       "person_count": person_count}

            self.insert_attendance_event_to_mongo(payload)

    def insert_attendance_event_to_mongo(self, data):
        try:
            input_data = {
                "eventId": str(uuid1()).split('-')[0],
                "cameraId": data['deviceId'],
                "cameraName": self.camera_mapping_json.get(data['deviceId'], "iLens Camera"),
                "timestamp": datetime.now(),
                "frame": data['frame'],
                "eventtype": "Intrusion Detection",
                "bg_color": data["bg_color"],
                "font_color": data["font_color"],
                "intrusion_message": data["message"],
                "alert_sound": data["alert_sound"],
                "person_count": data["person_count"],
                "app": "text"
            }

            logger.debug("Pushing to Mongo..")
            self.attendance_event_collection.insert(input_data)
        except Exception as e:
            logger.error(f"Exception occurred: {e}", exc_info=True)


class NotificationFilter(object):

    def __init__(self, ttl_value=3):
        """init function
        """
        global TTL
        TTL = ttl_value
        self.TTL = ttl_value
        self.face_id_cache = {}

    def _update_cache(self, name):
        """updates the cache with a name

        Args:
            name (str): Name of the person
        """
        self.face_id_cache[name] = time.time()

    def check_rpt(self, name):
        """Returns a boolean if the notification center has to be notified
        or not

        Args:
            name (str): name of person identified

        Returns:
            notify (bool): True if notification to be sent False if the
            notification is not to be sent
        """
        self._clean_up_cache()
        if name is None:
            notify = False
        else:
            is_present = self.face_id_cache.get(name, -1)
            if is_present == -1:
                notify = True
                self._update_cache(name)
            else:
                notify = False
        return notify

    @cached(cache=TTLCache(maxsize=1024, ttl=TTL))
    def _clean_up_cache(self):
        """Cleans up the cached name at regular interval
        """
        key_to_delete = []
        for key, value in self.face_id_cache.items():
            if time.time() - value >= self.TTL:
                key_to_delete.append(key)
        for key in key_to_delete:
            del self.face_id_cache[key]
