import time
import json
from datetime import datetime
from logging import Logger
from threading import Thread

from mbcontextmessagehandler import MbContextMessageBus
from messagebus import Event

from externals.repository import AlertsRepository


class RetrySentEventService(Thread):
    def __init__(
        self,
        message_bus,        # type: MbContextMessageBus
        alerts_repository,  # type: AlertsRepository
        time_to_call,       # type: int
        logger,             # type: Logger
    ):
        # type: (...) -> None

        super(RetrySentEventService, self).__init__()
        self.running = True
        self.daemon = True
        self.message_bus = message_bus
        self.time_to_call = time_to_call
        self.alerts_repository = alerts_repository
        self.logger = logger
        self.event_action = "PosAlertNotification"

    def _sleep(
        self,
    ):
        # type: (...) -> None

        time.sleep(self.time_to_call * 60)

    def send_event(
        self,
        event_data    # type: str
    ):
        # type: (...) -> None

        event_to_send = Event(
            subject=self.event_action,
            event_type="",
            data=event_data,
        )
        self.message_bus.publish_event(event=event_to_send)

    def handle_events_repository(
        self,
    ):
        # type: (...) -> None

        events = self.alerts_repository.get_events_with_sent_status(sent_status=0)
        for event in events:
            event['notification_json'] = json.loads(event.get('notification_json', {}))

            try:
                event_time = datetime.strptime(event.get('time_stamp'), '%Y-%m-%d %H:%M:%S.%f')
            except ValueError:
                event_time = datetime.strptime(event.get('time_stamp'), '%Y-%m-%d %H:%M:%S')

            fade_time = int(event.get('notification_json').get('alertJSON', {}).get('fadeTime', 0))
            if (datetime.utcnow() - event_time).total_seconds() > fade_time:
                self.alerts_repository.set_sent_status(
                    event_id=event.get('id'),
                    sent_status=-1,
                )
            else:
                event_data = json.dumps(obj=event.get('notification_json'))
                self.logger.info("Sending event with event_id: {} and data: {}".format(event.get('id'), event_data))
                self.send_event(event_data=event_data)

    def run(
        self,
    ):
        while self.running:
            try:
                self.handle_events_repository()
            except Exception as ex:
                self.logger.warning("Error in RetrySentEventService", exc_info=ex)
            finally:
                self._sleep()
