"""File containing infoscreen views."""

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import permission_required, login_required
from django.db import DatabaseError
from infoscreen.models import UploadFileForm

import sikweb.settings as settings
import json
import logging
import threading
import requests

from infoscreen.models import (
    Rotation,
    InfoItem,
    InfoInstance,
    ABBInfoItem,
    ExternalImageInfoItem,
    ImageInfoItem,
    SossoInfoItem,
    LunchItem,
    EventInfoItem,
    ExternalWebsiteInfoItem,
    ImageUploadForm,
    ApyInfoItem,
    VideoInfoItem,
)


@login_required(login_url="/admin/login")
@permission_required("infoscreen.change_infoinstance", raise_exception=True)
def admin(request, *args, **kwargs):
    """Render infoscreen admin page."""
    return render(request, "infoscreen/infoscreen_admin.html", {})


def create_item_generator(model):
    """Create Infoscreen item generator."""

    @ensure_csrf_cookie
    @require_http_methods(["POST"])
    @login_required(login_url="/admin/login")
    @permission_required("infoscreen.add_infoinstance", raise_exception=True)
    def create_item(request, *args, **kwargs):
        try:
            data = json.loads(request.body.decode("utf-8"))
        except json.JSONDecodeError:
            return HttpResponseBadRequest(
                '{"status":"failure","error":"invalid json supplied"}'
            )
        try:
            model.create_from_dict(data)
            return HttpResponse('{"status":"success"}')
        except RuntimeError as e:
            return HttpResponseBadRequest(
                json.dumps({"status": "failure", "error": str(e)})
            )

    return create_item


def delete_item_generator(model):
    """Delete Infoscreen item generator."""

    @ensure_csrf_cookie
    @require_http_methods(["DELETE"])
    @login_required(login_url="/admin/login")
    @permission_required("infoscreen.delete_infoinstance", raise_exception=True)
    def delete_item(request, *args, **kwargs):
        idx = kwargs.pop("idx", 0)
        try:
            item = model.objects.get(pk=idx)
        except model.DoesNotExist:
            resp = HttpResponse('{"error":"object not found"}')
            resp.status_code = 404
            return resp
        try:
            item.delete()
            return HttpResponse('{"status":"success"}')
        except DatabaseError:
            resp = HttpResponse('{"error" : "could not delete item"}')
            resp.status_code = 500
            return resp

    return delete_item


# due to model structure this is little complicated
@ensure_csrf_cookie
@login_required(login_url="/admin/login")
@permission_required("infoscreen.delete_infoinstance", raise_exception=True)
@require_http_methods(["DELETE"])
def delete_info_item(request, *args, **kwargs):
    """Delete info item."""
    type_id = kwargs.pop("type_id", 0)
    idx = kwargs.pop("idx", 0)
    if True:
        ct = ContentType.objects.get_for_id(type_id)
        item = ct.get_object_for_this_type(pk=idx)
    else:
        resp = HttpResponse('{"error":"object not found"}')
        resp.status_code = 404
        return resp
    try:
        item.delete()
        return HttpResponse('{"status":"success"}')
    except DatabaseError:
        resp = HttpResponse('{"error" : "could not delete item"}')
        resp.status_code = 500
        return resp


@require_http_methods(["POST"])
@ensure_csrf_cookie
@login_required(login_url="/admin/login")
@permission_required("infoscreen.add_infoinstance", raise_exception=True)
def create_image_item(request, *args, **kwargs):
    """Create image Infoscreen item."""
    form = ImageUploadForm(request.POST, request.FILES)
    if not form.is_valid():
        return HttpResponseBadRequest(
            '{"status": "failure",' '"error": "invalid data supplied"}'
        )

    img = form.cleaned_data["image"]
    name = form.cleaned_data["name"]
    ImageInfoItem.objects.create(img=img, name=name)
    return HttpResponse('{"status":"success"}')


@require_http_methods(["POST"])
@ensure_csrf_cookie
@login_required(login_url="/admin/login")
@permission_required("infoscreen.add_infoinstance", raise_exception=True)
def create_video_item(request, *args, **kwargs):
    """Create video Infoscreen item."""
    form = UploadFileForm(request.POST, request.FILES)
    if not form.is_valid():
        return HttpResponseBadRequest(
            '{"status": "failure",' '"error": "invalid data supplied"}'
        )

    video = form.cleaned_data["video"]
    name = form.cleaned_data["name"]
    VideoInfoItem.objects.create(video=video, name=name)
    return HttpResponse('{"status": "success"}')


@require_http_methods(["POST"])
@ensure_csrf_cookie
@login_required(login_url="/admin/login")
@permission_required("infoscreen.add_rotation", raise_exception=True)
def create_rotation(request, *args, **kwargs):
    """Create rotation."""
    try:
        data = json.loads(request.body.decode("utf-8"))
    except json.JSONDecodeError:
        return HttpResponse('{"error": "bad post body!"}', status=400)

    try:
        name = data["name"]
        Rotation.objects.create(name=name)
        resp = HttpResponse(status=200)
    except DatabaseError:
        resp = HttpResponse('{"error" : "could not create rotation!"}', status=400)

    return resp


@require_http_methods(["DELETE"])
@ensure_csrf_cookie
@login_required(login_url="/admin/login")
@permission_required("infoscreen.delete_rotation", raise_exception=True)
def delete_rotation(request, *args, **kwargs):
    """Delete rotation."""
    id = kwargs.pop("id", 0)
    logging.warning("Deleting rotation with id={}".format(id))

    try:
        Rotation.objects.filter(id=id).delete()
        resp = HttpResponse(status=200)
    except DatabaseError:
        resp = HttpResponse('{"error" : "could not delete rotation!"}', status=400)

    return resp


createInstance = create_item_generator(InfoInstance)
deleteInstance = delete_item_generator(InfoInstance)
createABBItem = create_item_generator(ABBInfoItem)
createSossoItem = create_item_generator(SossoInfoItem)
createLunchItem = create_item_generator(LunchItem)
createExternalImageInfoItem = create_item_generator(ExternalImageInfoItem)
createExternalWebsiteItem = create_item_generator(ExternalWebsiteInfoItem)
createEventItem = create_item_generator(EventInfoItem)
createApyItem = create_item_generator(ApyInfoItem)
createVideoItem = create_item_generator(VideoInfoItem)
