# Create your views here.

import datetime

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.core.mail import send_mail
from django.http import HttpResponse
from django.views.generic import TemplateView, FormView, UpdateView, CreateView
from django.shortcuts import render, redirect
from .booking_functions.availability import check_availability, calculate_price
from .forms import ContactForm, AvailabilityForm, BookRequestForm, EditBooking
from .models import Room, Booking, Pricing
#from datetime import datetime

def date_range(start, end, intv):
    diff = (end - start) / intv
    for i in range(intv):
        yield start + diff * i
    yield end


def get_range_data(date_pre, date_post, data_dict, operation, partitions):
    l_range = list(date_range(date_pre, date_post, partitions))
    d_range = {}
    for i in range(len(l_range)):
        try:
            d_range[l_range[i], l_range[i + 1]] = 0
        except IndexError:
            pass

    for k in data_dict.keys():
        for r in d_range.keys():
            if r[0] <= data_dict[k].check_in <= r[1]:
                if operation == 'bookings':
                    d_range[r] += 1
                if operation == 'income':
                    d_range[r] += data_dict[k].final_price
    return d_range


def get_statistics(stats_type):
    date_look = datetime.date.today()
    date_look_pre_week = date_look - datetime.timedelta(days=7)
    date_look_pre_month = date_look - datetime.timedelta(days=31)
    date_look_pre_3months = date_look - datetime.timedelta(days=93)
    date_look_pre_6months = date_look - datetime.timedelta(days=186)
    date_look_pre_year = date_look - datetime.timedelta(days=365)
    bookings = Booking.objects.all()

    bookings_week = {b.id: b for b in
                     bookings.filter(check_in__range=[date_look_pre_week, date_look]).filter(accept='NΑΙ')}
    bookings_month = {b.id: b for b in
                      bookings.filter(check_in__range=[date_look_pre_month, date_look]).filter(accept='NΑΙ')}
    bookings_3months = {b.id: b for b in
                        bookings.filter(check_in__range=[date_look_pre_3months, date_look]).filter(accept='NΑΙ')}
    bookings_6months = {b.id: b for b in
                        bookings.filter(check_in__range=[date_look_pre_6months, date_look]).filter(accept='NΑΙ')}
    bookings_year = {b.id: b for b in
                     bookings.filter(check_in__range=[date_look_pre_year, date_look]).filter(accept='NΑΙ')}

    d_range_week = get_range_data(date_look_pre_week, date_look, bookings_week, operation=stats_type, partitions=7)
    d_range_month = get_range_data(date_look_pre_month, date_look, bookings_month, operation=stats_type, partitions=10)
    d_range_3months = get_range_data(date_look_pre_3months, date_look, bookings_3months, operation=stats_type,
                                     partitions=6)
    d_range_6months = get_range_data(date_look_pre_6months, date_look, bookings_6months, operation=stats_type,
                                     partitions=6)
    d_range_year = get_range_data(date_look_pre_year, date_look, bookings_year, operation=stats_type, partitions=12)

    data = {}
    data["week_labels"] = ','.join(
        ['{}-{}'.format(i[0].strftime("%d/%m"), i[1].strftime("%d/%m")) for i in d_range_week.keys()])
    data["week_values"] = ','.join([str(i) for i in d_range_week.values()])
    data["month_labels"] = ','.join(
        ['{}-{}'.format(i[0].strftime("%d/%m"), i[1].strftime("%d/%m")) for i in d_range_month.keys()])
    data["month_values"] = ','.join([str(i) for i in d_range_month.values()])
    data["three_months_labels"] = ','.join(
        ['{}-{}'.format(i[0].strftime("%d/%m"), i[1].strftime("%d/%m")) for i in d_range_3months.keys()])
    data["three_months_values"] = ','.join([str(i) for i in d_range_3months.values()])
    data["six_months_labels"] = ','.join(
        ['{}-{}'.format(i[0].strftime("%d/%m"), i[1].strftime("%d/%m")) for i in d_range_6months.keys()])
    data["six_months_values"] = ','.join([str(i) for i in d_range_6months.values()])
    data["year_labels"] = ','.join(
        ['{}-{}'.format(i[0].strftime("%d/%m"), i[1].strftime("%d/%m")) for i in d_range_year.keys()])
    data["year_values"] = ','.join([str(i) for i in d_range_year.values()])
    data["active_page"] = 'statistics'
    return data


class IndexPageView(TemplateView):
    template_name = "index.html"
    # return HttpResponse(settings.LOCALE_PATHS)


class VillasPageView(TemplateView):
    template_name = "villas.html"

    def get_context_data(self, **kwargs):
        context = super(VillasPageView, self).get_context_data(**kwargs)
        m1_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                          season_end__gte=datetime.date.today(), category__exact="ΜΕΖ1")
        m2_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                          season_end__gte=datetime.date.today(), category__exact="ΜΕΖ2")
        context['m1_price'] = m1_price[0].price
        context['m2_price'] = m2_price[0].price
        return context


class RoomsPageView(TemplateView):
    template_name = "rooms.html"


class DoubleRoomsPageView(TemplateView):
    template_name = "double.html"

    def get_context_data(self, **kwargs):
        context = super(DoubleRoomsPageView, self).get_context_data(**kwargs)
        curr_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                            season_end__gte=datetime.date.today(), category__exact="ΔΙΚ")
        try:
           context['price'] = curr_price[0].price
        except IndexError:
           context['price'] = ''
        return context


class TripleRoomsPageView(TemplateView):
    template_name = "triple.html"

    def get_context_data(self, **kwargs):
        context = super(TripleRoomsPageView, self).get_context_data(**kwargs)
        t1_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                          season_end__gte=datetime.date.today(), category__exact="ΤΡΙ1")
        t2_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                          season_end__gte=datetime.date.today(), category__exact="ΤΡΙ2")
        t3_price = Pricing.objects.filter(season_start__lte=datetime.date.today(),
                                          season_end__gte=datetime.date.today(), category__exact="ΤΡΙ3")
        try:
            context['t1_price'] = t1_price[0].price
        except IndexError:
            context['t1_price'] = ''
        try:
            context['t2_price'] = t2_price[0].price
        except IndexError:
            context['t1_price'] = ''
        try:
            context['t3_price'] = t3_price[0].price
        except IndexError:
            context['t1_price'] = ''
        return context


class AboutPageView(TemplateView):
    template_name = "about.html"


class LocationPageView(TemplateView):
    template_name = "location.html"


class ContactPageView(FormView):
    form_class = ContactForm
    template_name = "contact.html"
    success_url = 'contact'

    def form_valid(self, form):
        message = "{name} / {email} said: ".format(
            name=form.cleaned_data.get('name'),
            email=form.cleaned_data.get('email'))
        message += "\n\n{0}".format(form.cleaned_data.get('message'))
        send_mail(
            subject=form.cleaned_data.get('subject').strip(),
            message=message,
            from_email='contact-form@alion.gr',
            recipient_list=[settings.LIST_OF_EMAIL_RECIPIENTS],
        )
        return super(ContactPageView, self).form_valid(form)


class FavailFormView(FormView):
    form_class = AvailabilityForm
    template_name = "book.html"
    success_url = 'book_dates'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context

    def post(self, request, context_dict={}, *args, **kwargs):
        form = AvailabilityForm(request.POST)
        if form.is_valid():
            category = form.cleaned_data['room_category']
            room_list = Room.objects.filter(category=category)
            data = form.cleaned_data
            available_rooms = []
            for room in room_list:
                if check_availability(room, data['check_in'], data['check_out']):
                    available_rooms.append(room)
            if len(available_rooms) > 0:
                total_price = calculate_price(data['check_in'], data['check_out'], category)
                avail_msg = 'There are available rooms from {} to {}'.format(data['check_in'].strftime("%d/%m/%Y"), data['check_out'].strftime("%d/%m/%Y"))
                context_dict.update({"available": True,
                                     "booking": True,
                                     'check_in': data['check_in'],
                                     'check_out': data['check_out'],
                                     'room_category': data['room_category'],
                                     'anchor': 'fa',
                                     'avail_msg': avail_msg,
                                     })
                request.session['check_in'] = str(data['check_in'])
                request.session['check_out'] = str(data['check_out'])
                request.session['room_category'] = str(data['room_category'])
                request.session['anchor'] = 'fa'
                request.session['avail_msg'] = avail_msg
                request.session['total_price'] = total_price
                return redirect('alion_app:book_dates')
            else:
                messages.error(request, 'No available rooms')


class BookingFormView(FormView):
    form_class = BookRequestForm
    template_name = "book_dates.html"
    success_url = 'book_success'

    def get(self, request, context_dict={}, *args, **kwargs):
        context_dict.update({"available": True,
                             "booking": True,
                             'check_in': request.session['check_in'],
                             'check_out': request.session['check_out'],
                             'room_category': request.session['room_category'],
                             'anchor': request.session['anchor'],
                             'avail_msg':  request.session['avail_msg'],
                             'total_price': request.session['total_price'],
                             'form': BookRequestForm()
                             })
        return render(request, "book_dates.html", context_dict)

    def post(self, request, context_dict={}, *args, **kwargs):
        form = BookRequestForm(request.POST)
        check_in = datetime.datetime.strptime(request.session['check_in'], '%Y-%m-%d')
        check_out = datetime.datetime.strptime(request.session['check_out'], '%Y-%m-%d')
        context_dict.update({'check_in': check_in,
                             'check_out': check_out,
                             'room_category': request.session['room_category'],
                             'anchor': request.session['anchor'],
                             'avail_msg': request.session['avail_msg'],
                             'total_price': request.session['total_price'],
                             'form': form
                             })
        if form.is_valid():
            data = form.cleaned_data
            booking = Booking.objects.create(
                name=data['name'],
                surname=data['surname'],
                telephone=data['telephone'],
                email=data['email'],
                category=context_dict['room_category'],
                room=Room.objects.get(number='001'),
                check_in=context_dict['check_in'],
                check_out=context_dict['check_out'],
                final_price=context_dict['total_price'],
                info=data['info'],
                accept='ΝΕΟ',
            )
            booking.save()
            message = "{} - from {} until {}\n\nTotal Price {}\n\nInfo:{}\n{} {}\ntel:{}\nemail:{}\n\nAdmin Link: http://127.0.0.1:8000/dx/{}/update".format(context_dict['room_category'], context_dict['check_in'], context_dict['check_out'], context_dict['total_price'], data['info'], data['name'], data['surname'], data['telephone'], data['email'], booking.id)
            send_mail(
            subject="Booking Request {} {}".format(data['name'], data['surname']),
            message=message,
            from_email='booking-form@alion.gr',
            recipient_list=[settings.LIST_OF_EMAIL_RECIPIENTS],
            )

            return render(request, "book_success.html", context=context_dict)
        else:
            messages.error(request, form.errors)
            return render(request, "book_dates.html", context=context_dict)


class RoomAvailabilityFormView(FormView):
    form_class = AvailabilityForm
    template_name = "diaxeirisi/Dashboard.Rooms.Availability.html"
    success_url = '/dx/room_availability'

    def post(self, request, context_dict={}, *args, **kwargs):
        form = AvailabilityForm(request.POST)
        if form.is_valid():
            category = form.cleaned_data['room_category']
            room_list = Room.objects.filter(category=category)
            data = form.cleaned_data
            available_rooms = []
            for room in room_list:
                if check_availability(room, data['check_in'], data['check_out']):
                    available_rooms.append(room)
            if len(available_rooms) > 0:
                context_dict.update({"form": form,
                                     'available_rooms': available_rooms,
                                     'RoomObj': available_rooms
                                     })
                return render(request, "diaxeirisi/Dashboard.Rooms.Availability.html", context=context_dict)


class DashboardPageView(LoginRequiredMixin, TemplateView):
    form_class = EditBooking
    template_name = "diaxeirisi/Dashboard.Default.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["BookingObj"] = Booking.objects.all()
        context["active_page"] = 'dashboard'
        return context


class RoomsDXPageView(LoginRequiredMixin, TemplateView):
    template_name = "diaxeirisi/Dashboard.Rooms.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["RoomObj"] = Room.objects.all()
        date_look = datetime.date.today()
        date_look_pre = date_look - datetime.timedelta(days=30)
        booked = {}
        for i in Booking.objects.filter(check_in__range=[date_look_pre, date_look]):
            if i.check_in <= date_look < i.check_out:
                booked[i.room.id] = {'b_id': i.id, 'b_name': i.name, 'b_surname': i.surname}
        context["Booked"] = booked
        context["active_page"] = 'rooms'
        return context


class EditBookingView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
    model = Booking
    success_url = '/dx'
    success_message = 'Οι αλλαγές αποθηκεύτηκαν.'
    template_name = "diaxeirisi/edit_booking.html"
    fields = [
        "name",
        "surname",
        "telephone",
        "email",
        "category",
        "room",
        "check_in",
        "check_out",
        "final_price",
        "country",
        "info",
        "accept"
    ]

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        category = context["object"].category
        room_list = Room.objects.filter(category=category)
        available_rooms = []
        for room in room_list:
            if check_availability(room, context["object"].check_in, context["object"].check_out):
                available_rooms.append(room)
        context["AvailRooms"] = available_rooms
        return context


class CreateBooking(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Booking
    success_url = '/dx'
    success_message = 'H Κράτηση Δημιουργήθηκε.'
    template_name = "diaxeirisi/create_booking.html"
    fields = [
        "name",
        "surname",
        "telephone",
        "email",
        "category",
        "room",
        "check_in",
        "check_out",
        "final_price",
        "country",
        "info",
        "accept"
    ]


class EditRoomView(LoginRequiredMixin, UpdateView):
    model = Room
    template_name = "diaxeirisi/edit_room.html"
    fields = [
        "number",
        "category",
        "beds",
        "capacity",
    ]

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context


class CreateRoom(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Room
    success_url = '/dx/create_room'
    success_message = 'Οι αλλαγές αποθηκεύτηκαν.'
    template_name = "diaxeirisi/create_room.html"
    fields = [
        "number",
        "category",
        "beds",
        "capacity",
    ]


class StatisticsPageView(LoginRequiredMixin, TemplateView):
    template_name = "diaxeirisi/Dashboard.Statistics.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        stats = get_statistics('bookings')
        context.update(stats)
        return context


class StatisticsIncomePageView(LoginRequiredMixin, TemplateView):
    template_name = "diaxeirisi/Dashboard.Statistics.Income.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        stats = get_statistics('income')
        context.update(stats)
        return context
