from django.db import models
from django.db.models.fields.related import RelatedField
from django.http.response import JsonResponse


import json


def generic_edit(model, request, id=None):
    """Create/edit generic object view."""

    if id:
        item = model.objects.filter(id=id, author=request.user.setting).first()

    else:
        item = model(author=request.user.setting)

    if not item:
        return JsonResponse({}, status=404)

    if request.method == "DELETE":
        try:
            item.delete()

        except Exception:
            return JsonResponse({"error": "INVALID_DELETE"}, status=401)

        return JsonResponse({})

    if request.method != "POST":
        return JsonResponse({}, status=405)

    try:
        data = json.loads(request.body)

    except Exception:
        return JsonResponse({"error": "INVALID_DATA"}, status=401)

    for field in item._meta.fields:
        if field.name in item.Serialization.excluded_fields_edit:
            continue

        if isinstance(field, RelatedField):
            if isinstance(field, models.ForeignKey):

                # Also allow for nested object (giving the full object instead of the id only)
                if isinstance(data[field.name], dict):
                    setattr(item, f"{field.name}_id", data[field.name]["id"])

                else:
                    setattr(item, f"{field.name}_id", data[field.name])

            # For now, disregard m2m fields
            continue

        if field.name not in data:
            continue

        setattr(item, field.name, data[field.name])

    try:
        item.save()

    except Exception:
        return JsonResponse({"error": "DATA_INVALID"}, status=401)

    return JsonResponse(
        {
            "object": item.serialize(),
        }
    )
