from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.views import View
from django.views.generic import DetailView

from analysis.forms import TimespanReportForm
from analysis.utils.excel.excel import TempExcelFile
from analysis.utils.report import TimespanReport
from codelist.models import KonovaCode
from konova.contexts import BaseContext
from konova.decorators import conservation_office_group_required
from konova.utils.message_templates import FORM_INVALID, PARAMS_INVALID


@login_required
@conservation_office_group_required
def index_reports_view(request: HttpRequest):
    """

    Args:
        request (HttpRequest): The incoming request

    Returns:

    """
    template = "analysis/reports/index.html"
    form = TimespanReportForm(request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            redirect_url = form.save()
            return redirect(redirect_url)
        else:
            messages.error(
                request,
                FORM_INVALID,
                extra_tags="danger",
            )
    context = {
        "form": form
    }
    context = BaseContext(request, context).context
    return render(request, template, context)

class ReportIndexView(LoginRequiredMixin, View):
    @method_decorator(conservation_office_group_required)
    def get(self, request: HttpRequest) -> HttpResponse:

        """

        Args:
            request (HttpRequest): The incoming request

        Returns:

        """
        template = "analysis/reports/index.html"
        form = TimespanReportForm(None)
        context = {
            "form": form
        }
        context = BaseContext(request, context).context
        return render(request, template, context)

    @method_decorator(conservation_office_group_required)
    def post(self, request: HttpRequest) -> HttpResponse:

        """

        Args:
            request (HttpRequest): The incoming request

        Returns:

        """
        template = "analysis/reports/index.html"
        form = TimespanReportForm(request.POST or None)
        if form.is_valid():
            redirect_url = form.save()
            return redirect(redirect_url)
        else:
            messages.error(
                request,
                FORM_INVALID,
                extra_tags="danger",
            )
        context = {
            "form": form
        }
        context = BaseContext(request, context).context
        return render(request, template, context)


class ReportDetailView(LoginRequiredMixin, DetailView):

    @method_decorator(conservation_office_group_required)
    def get(self, request: HttpRequest, id: str):
        """ Renders the detailed report for a conservation office

        Args:
            request (HttpRequest): The incoming request
            id (str): The conservation_office KonovaCode id

        Returns:

        """
        # Try to resolve the requested office id
        cons_office = get_object_or_404(
            KonovaCode,
            id=id
        )
        # Try to resolve the date parameters into Date objects -> redirect if this fails
        try:
            df = request.GET.get("df", None)
            dt = request.GET.get("dt", None)
            date_from = timezone.make_aware(timezone.datetime.fromisoformat(df))
            date_to = timezone.make_aware(timezone.datetime.fromisoformat(dt))
        except ValueError:
            messages.error(
                request,
                PARAMS_INVALID,
                extra_tags="danger",
            )
            return redirect("analysis:reports")

        # Check whether the html default rendering is requested or an alternative
        format_param = request.GET.get("format", "html")
        report = TimespanReport(id, date_from, date_to)

        if format_param == "html":
            return self.__handle_html_format(request, report, cons_office)
        elif format_param == "excel":
            return self.__handle_excel_format(report, cons_office, df, dt)
        else:
            raise NotImplementedError

    def __handle_html_format(self, request, report: TimespanReport, office: KonovaCode):
        template = "analysis/reports/detail.html"
        context = {
            "office": office,
            "report": report,
        }
        context = BaseContext(request, context).context
        return render(request, template, context)

    def __handle_excel_format(self, report: TimespanReport, office: KonovaCode, df: str, dt: str):
        file = TempExcelFile(report.excel_template_path, report.excel_map)
        response = HttpResponse(
            content=file.stream,
            content_type="application/ms-excel",
        )
        response['Content-Disposition'] = f'attachment; filename={office.long_name}_{df}_{dt}.xlsx'
        return response
