from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import permissions
from .models import (
    {%- for mod in full_model.models %}
    {{mod.name}},
    {%- endfor %}
)
from .serializers import (
    {%- for mod in full_model.models %}
    {{mod.name}}Serializer,
    {%- endfor %}
)

{% for mod in full_model.models %}
class {{mod.name}}ListApiView(APIView):
    # add permission to check if user is authenticated
    # permission_classes = [permissions.IsAuthenticated]

    # 1. List all
    def get(self, request, *args, **kwargs):
        """
        List all the {{mod.name.lower()}} items.
        """
        {{mod.name.lower()}}s = {{mod.name}}.objects.all()
        serializer = {{mod.name}}Serializer({{mod.name.lower()}}s, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 2. Create
    def post(self, request, *args, **kwargs):
        """
        Create the {{mod.name}} with given {{mod.name.lower()}} data
        """
        data = {
            {%- for attrib in mod.attributs -%}
            {%- if attrib.type == "reference" and attrib.model == "User" %}
            "{{ attrib.name }}": request.user.id,
            {%- else %}
            "{{ attrib.name }}": request.data.get("{{ attrib.name }}"),
            {%- endif -%}
            {%- endfor %}
        }
        serializer = {{mod.name}}Serializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class {{mod.name}}DetailApiView(APIView):
    # add permission to check if user is authenticated
    # permission_classes = [permissions.IsAuthenticated]
{%- if mod.name != "User" %}
    def get_object(self, {{mod.name.lower()}}_id):
        """
        Helper method to get the object with given {{mod.name.lower()}}_id
        """
        try:
            return {{mod.name}}.objects.get(id={{mod.name.lower()}}_id)
        except {{mod.name}}.DoesNotExist:
            return None
{%- endif -%}
    # 3. Retrieve
    def get(self, request, {{mod.name.lower()}}_id, *args, **kwargs):
        """
        Retrieves the {{mod.name}} with given {{mod.name.lower()}}_id
        """
        {{mod.name.lower()}}_instance = self.get_object({{mod.name.lower()}}_id, request.user.id)
        if not {{mod.name.lower()}}_instance:
            return Response(
                {"res": "Object with {{mod.name.lower()}} id does not exists"},
                status=status.HTTP_400_BAD_REQUEST
            )

        serializer = {{mod.name}}Serializer({{mod.name.lower()}}_instance)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 4. Update
    def put(self, request, {{mod.name.lower()}}_id, *args, **kwargs):
        """
        Updates the {{mod.name.lower()}} item with given {{mod.name.lower()}}_id if exists
        """
        {{mod.name.lower()}}_instance = self.get_object({{mod.name.lower()}}_id, request.user.id)
        if not {{mod.name.lower()}}_instance:
            return Response(
                {"res": "Object with {{mod.name.lower()}} id does not exists"},
                status=status.HTTP_400_BAD_REQUEST
            )
        data = {
            {%- for attrib in mod.attributs -%}
            {%- if attrib.type == "reference" and attrib.model == "User" %}
            "{{ attrib.name }}": request.user.id,
            {%- else %}
            "{{ attrib.name }}": request.data.get("{{ attrib.name }}"),
            {%- endif -%}
            {%- endfor %}
        }
        serializer = {{mod.name}}Serializer(instance = {{mod.name.lower()}}_instance, data=data, partial = True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # 5. Delete
    def delete(self, request, {{mod.name.lower()}}_id, *args, **kwargs):
        """
        Deletes the {{mod.name.lower()}} item with given {{mod.name.lower()}}_id if exists
        """
        {{mod.name.lower()}}_instance = self.get_object({{mod.name.lower()}}_id, request.user.id)
        if not {{mod.name.lower()}}_instance:
            return Response(
                {"res": "Object with {{mod.name.lower()}} id does not exists"},
                status=status.HTTP_400_BAD_REQUEST
            )
        {{mod.name.lower()}}_instance.delete()
        return Response(
            {"res": "Object deleted!"},
            status=status.HTTP_200_OK
        )
{% endfor %}
