from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.apps import apps
from .models import Character, PackageFeature, Feature, Pin, Package, ObjectTrait
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Pin
from .serializers import PinSerializer

import json

# Create your views here.

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.template.loader import render_to_string
from django.views.decorators.http import require_GET

@require_GET
def feature_select_search(request):
    system = request.GET.get('system')
    q = request.GET.get('q', '').strip()
    page = request.GET.get('page', 1)
    per_page = 5
    print(q, system, page)
    feats = Feature.objects.all()
    if system:
        feats = feats.filter(feature_system=system)
    if q:
        feats = feats.filter(
            feature_name__icontains=q
        )

    paginator = Paginator(feats.order_by('feature_name'), per_page)
    try:
        page_obj = paginator.page(page)
    except PageNotAnInteger:
        page_obj = paginator.page(1)
    except EmptyPage:
        page_obj = paginator.page(paginator.num_pages)

    data = {
        'results': [
            {
                'id': str(feat.id),
                'feature_name': feat.feature_name,
                'feature_description': feat.feature_description,
            }
            for feat in page_obj.object_list
        ],
        'page': page_obj.number,
        'num_pages': paginator.num_pages,
        'has_previous': page_obj.has_previous(),
        'has_next': page_obj.has_next(),
    }
    return JsonResponse(data)

def home(request):
    with open('test_character.json', 'r+') as file:
        character = json.load(file)

    character = Character.objects.get(name="Gerom")
    class_feature_links = (
        PackageFeature.objects
        .filter(package=character.char_class)
        .select_related('feature')
        .order_by('priority')
    )
    character.char_class.display_features = class_feature_links
    return render(request, 'main/character_sheet.html', {'character': character, })
    return render(request, 'main/character_sheet.html')


def package_detail(request, system, package_uuid):
    package = get_object_or_404(Package, id=package_uuid)
    
    if request.method == 'POST':
        try:
            payload = json.loads(request.POST.get('package_payload'))

            package.package_name = payload.get('package_name')
            package.package_description = payload.get('package_description')
            package.package_requirements = payload.get('package_requirements')
            package.package_doc_md = payload.get('package_doc_md')
            package.package_operations = payload.get('package_operations')
            package.package_type = payload.get('package_type')

            trait_ids = [trait['id'] for trait in payload.get('package_traits', [])]
            print(trait_ids)
            if trait_ids is not None:
                package.package_traits.set(trait_ids)

            feat_ids = [feat['id'] for feat in payload.get('features', [])]
            print(feat_ids)
            if trait_ids is not None:
                package.features.set(feat_ids)

            package.save()

            return HttpResponse('''
                <script>
                    UIkit.notification({message: "Feature Updated Successfully!", status: "success", pos: "top-center"})
                </script>
            ''')

        except Exception as e:
            return HttpResponse('''
                <script>
                    UIkit.notification({message: "Feature Update Unsuccessful, there appears to have been an error!", status: "danger", pos: "top-center"})
                </script>
            ''')

    elif request.method == 'GET':
        traits = package.package_traits.all()
        traits = [trait.to_json() for trait in traits]
        features = package.features.all()
        features = [feat.to_json() for feat in features]
        return render(request, 'main/test_package.html', {'system': system, 'package': package, 'traits': traits, 'features':features })


def package_new(request, system):
    if request.method == 'GET':
        return render(request, 'main/test_package.html', {'system': system})
    elif request.method == 'POST':
        payload_json = request.POST.get('package_payload')
        try:
            payload = json.loads(payload_json)
            print('---PAYLOAD---')
            print(json.dumps(payload, indent=2))
            feature = Feature.objects.create(
                feature_name=payload.get('feature_name'),
                feature_description=payload.get('feature_description'),
                feature_system=str(system),
                feature_requirements=payload.get('feature_requirements'),
                feature_data=payload.get('feature_data')
            )

            trait_ids = [trait['id'] for trait in payload.get('feature_traits', [])]


            if trait_ids is not None:
                feature.feature_traits.set(trait_ids)
            response = HttpResponse(status=204)
            response['HX-Redirect'] = f'/{system}/feature/{feature.id}'
            return response
        except Exception as e:
            print('Failed to parse payload:', str(e))
            payload = None

        return HttpResponse('<div class="uk-alert-success">Payload printed to server log.</div>', content_type="text/html")

def packages_list(request, system):
    packages = Package.objects.filter(package_system=system)
    return render(request, "main/packages_list.html", {
        "packages": packages,
        "system": system
    })     


def feature_detail(request, system, feature_uuid):
    feature = get_object_or_404(Feature, id=feature_uuid)
    
    if request.method == 'POST':
        try:
            payload = json.loads(request.POST.get('feature_payload'))

            feature.feature_name = payload.get('feature_name')
            feature.feature_description = payload.get('feature_description')
            feature.feature_requirements = payload.get('feature_requirements')
            feature.feature_data = payload.get('feature_data')

            feature.save()

            trait_ids = [trait['id'] for trait in payload.get('feature_traits', [])]
            print(trait_ids)
            if trait_ids is not None:
                feature.feature_traits.set(trait_ids)

            return HttpResponse('''
                <script>
                    UIkit.notification({message: "Feature Updated Successfully!", status: "success", pos: "top-center"})
                </script>
            ''')

        except Exception as e:
            return HttpResponse('''
                <script>
                    UIkit.notification({message: "Feature Update Unsuccessful, there appears to have been an error!", status: "danger", pos: "top-center"})
                </script>
            ''')

    elif request.method == 'GET':
        traits = feature.feature_traits.all()
        traits = [trait.to_json() for trait in traits]
        return render(request, 'main/test_feature.html', {'system': system, 'feature': feature, 'traits': traits })


def feature_new(request, system):
    if request.method == 'GET':
        return render(request, 'main/test_feature.html', {'system': system})
    elif request.method == 'POST':
        payload_json = request.POST.get('feature_payload')
        try:
            payload = json.loads(payload_json)
            print('---PAYLOAD---')
            print(json.dumps(payload, indent=2))
            feature = Feature.objects.create(
                feature_name=payload.get('feature_name'),
                feature_description=payload.get('feature_description'),
                feature_system=str(system),
                feature_requirements=payload.get('feature_requirements'),
                feature_data=payload.get('feature_data')
            )

            trait_ids = [trait['id'] for trait in payload.get('feature_traits', [])]


            if trait_ids is not None:
                feature.feature_traits.set(trait_ids)
            response = HttpResponse(status=204)
            response['HX-Redirect'] = f'/{system}/feature/{feature.id}'
            return response
        except Exception as e:
            print('Failed to parse payload:', str(e))
            payload = None

        return HttpResponse('<div class="uk-alert-success">Payload printed to server log.</div>', content_type="text/html")

def features_list(request, system):
    features = Feature.objects.filter(feature_system=system)
    return render(request, "main/features_list.html", {
        "features": features,
        "system": system
    })     

def map_page(request):
      return render(request, "main/map.html")

@api_view(['GET', 'POST'])
def pin_list(request):
    if request.method == 'GET':
        pins = Pin.objects.all()
        serializer = PinSerializer(pins, many=True)
        return Response(serializer.data)
    if request.method == 'POST':
        serializer = PinSerializer(data=request.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)

def trait_search(request):
    query = request.GET.get('q', '')
    system = request.GET.get('system', '')
    traits = ObjectTrait.objects.filter(trait_system=system, trait_name__icontains=query).values('id', 'trait_name')[:20]
    return JsonResponse(list(traits), safe=False)