import requests
from django.conf import settings
from django.core.paginator import Paginator
from django.http import HttpResponse
from django.shortcuts import render
from django_downloadview import ObjectDownloadView
from django_http_exceptions import HTTPExceptions
from guardian.shortcuts import get_objects_for_user

from .models import Contract, ContractFile


class ContractFileDownloadView(ObjectDownloadView):
    model = ContractFile
    file_field = "file"
    attachment = False

    def get_queryset(self, *args, **kwargs):
        queryset = super().get_queryset(*args, **kwargs)

        if not self.current_user.has_perm("contracts.view_confidential"):
            queryset = queryset.filter(is_public=True)

        return queryset

    def get(self, request, *args, **kwargs):
        self.current_user = request.user

        return super().get(request, *args, **kwargs)


def get_base_context(request) -> dict:
    return {
        "site_url": settings.SITE_URL,
        "user": request.user,
    }


def get_pagination(request, objects) -> tuple:
    paginator = Paginator(objects, 25)

    page = paginator.get_page(request.GET.get("page"))

    return page, paginator


def get_paginated_contracts(request, filter: dict = {}) -> tuple:
    filter["is_approved"] = True

    if not request.user.has_perm("contracts.view_confidential"):
        filter["is_public"] = True

    contracts = (
        get_objects_for_user(request.user, "contracts.view_contract")
        .filter(**filter)
        .order_by("valid_start_date")
        .all()
    )

    page, paginator = get_pagination(request, contracts)

    return page, paginator


def index(request):
    page, paginator = get_paginated_contracts(request)

    return render(
        request,
        "contracts/index.html",
        {
            **get_base_context(request),
            "title": "Seznam smluv",
            "description": "Description",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract(request, id: int):
    filter = {"is_approved": True}

    if not request.user.has_perm("contracts.view_confidential"):
        filter["is_public"] = True

    contract = (
        get_objects_for_user(request.user, "contracts.view_contract")
        .filter(**filter)
        .get(id=id)
    )

    return render(
        request,
        "contracts/view_contract.html",
        {
            **get_base_context(request),
            "title": contract.name,
            "description": contract.summary,
            "contract": contract,
        },
    )


# BEGIN Filtered contract + submodel views


def view_contract_filing_area(request, id: int):
    filing_area = get_objects_for_user(
        request.user, "contracts.view_contractfilingarea"
    ).get(id=id)

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, {"filing_area": filing_area}
    )

    return render(
        request,
        "contracts/view_contract_filing_area.html",
        {
            **get_base_context(request),
            "title": filing_area.name,
            "description": (
                f"Spisovna smluv - {filing_area.name}, "
                f"zodpovědná osoba {filing_area.person_responsible}"
            ),
            "filing_area": filing_area,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contract_issue(request, id: int):
    issue = get_objects_for_user(request.user, "contracts.view_contractissue").get(
        id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, {"issues": issue}
    )

    return render(
        request,
        "contracts/view_contract_issue.html",
        {
            **get_base_context(request),
            "title": issue.name,
            "description": f"Problém se smlouvami - {issue.name}",
            "issue": issue,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contract_type(request, id: int):
    type_ = get_objects_for_user(request.user, "contracts.view_contracttype").get(id=id)

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, {"types": type_}
    )

    return render(
        request,
        "contracts/view_contract_type.html",
        {
            **get_base_context(request),
            "title": type_.name,
            "description": f"Typ smluv - {type_.name}",
            "type": type_,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_contractee(request, id: int):
    contractee = get_objects_for_user(request.user, "contracts.view_contractee").get(
        id=id
    )

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, {"contractee_signatures__contractee": contractee}
    )

    return render(
        request,
        "contracts/view_contractee.html",
        {
            **get_base_context(request),
            "title": contractee.name,
            "description": f"Naše smluvní strana - {contractee.name}",
            "contractee": contractee,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


def view_signee(request, id: int):
    signee = get_objects_for_user(request.user, "contracts.view_signee").get(id=id)

    contracts_page, contracts_paginator = get_paginated_contracts(
        request, {"signee_signatures__signee": signee}
    )

    return render(
        request,
        "contracts/view_signee.html",
        {
            **get_base_context(request),
            "title": signee.name,
            "description": f"Jiná smluvní strana - {signee.name}",
            "signee": signee,
            "contracts_page": contracts_page,
            "contracts_paginator": contracts_paginator,
        },
    )


# END Filtered contract + submodel views

# BEGIN Submodel listing views


def view_contract_filing_areas(request):
    filing_areas = get_objects_for_user(
        request.user,
        "contracts.view_contractfilingarea",
    ).order_by("name")

    page, paginator = get_pagination(request, filing_areas)

    return render(
        request,
        "contracts/view_contract_filing_areas.html",
        {
            **get_base_context(request),
            "title": "Spisovny",
            "description": "Seznam fyzických spisoven, kde jsou ukládány smlouvy.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract_issues(request):
    issues = get_objects_for_user(
        request.user,
        "contracts.view_contractissue",
    ).order_by("name")

    page, paginator = get_pagination(request, issues)

    return render(
        request,
        "contracts/view_contract_issues.html",
        {
            **get_base_context(request),
            "title": (
                "Poznámky" if not request.user.can_view_confidential else "Problémy"
            ),
            "description": (
                "Poznámky ke smlouvám."
                if not request.user.can_view_confidential
                else "Problémy se smlouvami."
            ),
            "page": page,
            "paginator": paginator,
        },
    )


def view_contract_types(request):
    types = get_objects_for_user(
        request.user,
        "contracts.view_contracttype",
    ).order_by("name")

    page, paginator = get_pagination(request, types)

    return render(
        request,
        "contracts/view_contract_types.html",
        {
            **get_base_context(request),
            "title": "Typy",
            "description": "Typy smluv.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_contractees(request):
    contractees = get_objects_for_user(
        request.user,
        "contracts.view_contractee",
    ).order_by("name")

    page, paginator = get_pagination(request, contractees)

    return render(
        request,
        "contracts/view_contractees.html",
        {
            **get_base_context(request),
            "title": "Naše smluvní strany",
            "description": "Naše smluvní strany.",
            "page": page,
            "paginator": paginator,
        },
    )


def view_signees(request):
    contractees = get_objects_for_user(
        request.user,
        "contracts.view_signee",
    ).order_by("name")

    page, paginator = get_pagination(request, contractees)

    return render(
        request,
        "contracts/view_signees.html",
        {
            **get_base_context(request),
            "title": "Jiné smluvní strany",
            "description": "Jiné smluvní strany.",
            "page": page,
            "paginator": paginator,
        },
    )


# END Submodel listing views


# ARES CORS proxy
def get_ares_info(request, ico: int):
    if not request.user.is_staff:
        raise HTTPExceptions.FORBIDDEN

    ares_info = requests.get(
        f"https://wwwinfo.mfcr.cz/cgi-bin/ares/darv_std.cgi?ico={ico}"
    )

    return HttpResponse(
        content=ares_info.content,
        status=ares_info.status_code,
        content_type=ares_info.headers.get("Content-Type"),
    )