from django.db import models
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from utils.models import ProjectBaseMixin
from booking.models.services import LastableService, GuestonlineService
from account.models import User


class BookingManager(models.QuerySet):
    def by_user(self, user: User):
        return self.filter(user=user)


class Booking(ProjectBaseMixin):
    LASTABLE = 'L'
    GUESTONLINE = 'G'
    AVAILABLE_SERVICES = (
        (LASTABLE, 'Lastable'),
        (GUESTONLINE, 'GuestOnline')
    )
    type = models.CharField(max_length=2, choices=AVAILABLE_SERVICES, verbose_name=_('Guestonline or Lastable'))
    restaurant_id = models.TextField(verbose_name=_('booking service establishment id'), default=None)
    booking_user_locale = models.CharField(verbose_name=_('booking locale'), default='en', max_length=10)
    pending_booking_id = models.TextField(verbose_name=_('external service pending booking'), default=None)
    booking_id = models.TextField(verbose_name=_('external service booking id'), default=None, null=True,
                                  db_index=True, )
    stripe_key = models.TextField(null=True, default=None, verbose_name=_('stripe service payment key'))
    stripe_token = models.TextField(null=True, default=None, verbose_name=_('stripe service pre-payed booking token'))
    amount = models.CharField(null=True, default=None, verbose_name=_('prepayment price'), max_length=30)
    user = models.ForeignKey(
        'account.User', verbose_name=_('booking owner'), null=True,
        related_name='bookings',
        blank=True, default=None, on_delete=models.CASCADE)
    objects = BookingManager.as_manager()

    @property
    def accept_email_spam(self):
        return False

    @property
    def accept_sms_spam(self):
        return False

    @classmethod
    def get_service_by_type(cls, type):
        if type == cls.GUESTONLINE:
            return GuestonlineService()
        elif type == cls.LASTABLE:
            return LastableService()
        else:
            return None

    @classmethod
    def get_booking_id_by_type(cls, establishment, type):
        if type == cls.GUESTONLINE:
            return establishment.guestonline_id
        elif type == cls.LASTABLE:
            return establishment.lastable_id
        else:
            return None

    def delete(self, using=None, keep_parents=False):
        service = self.get_service_by_type(self.type)
        if not service.cancel_booking(self.booking_id):
            raise serializers.ValidationError(detail='Something went wrong! Unable to cancel.')
        super().delete(using, keep_parents)

    class Meta:
        verbose_name = _('Booking')
        verbose_name_plural = _('Booking')
