"""
informant_lookups/ajax.py
Author: Haidar Khazen
Created 7/2/20

AJAX Functions for Lookups

These are currently specific to each model. Todo: Generalize
"""

import json
from django.apps import apps
from django.http import HttpResponse, JsonResponse
from support.decorators import deny_get
from informant_erp.models import JobLog
from .models import Item
from support.utilities import get_building_as_str

def autocomplete_field(request):
    if request.is_ajax():
        term = request.GET.get('term')  # Main term for which to filter
        filter_term = request.GET.get('filter_term', 'undefined')  # Secondary term with which to filter
        filter_field = request.GET.get('filter_field', 'undefined') # Filter this field by the secondary term (these two used together)
        exclude_field = request.GET.get('exclude_field', 'undefined') # Field to be used with term for exclude
        exclude_term = request.GET.get('exclude_term', 'undefined')  # Secondary term used to exclude results
        model_class = request.GET.get('model_class') # Which table to search
        search_field = request.GET.get('search_field') # Which filed to filter on
        search_follow = request.GET.get('search_follow') # If main search field is a foreignkey, must follow to a string (usually the pk of the object referred to)
        ret_value = request.GET.get('ret_value', 'undefined') # If the pk is an id, use it when ID is needed
        ret_str = request.GET.get('ret_str', 'undefined') # If the search field is an object, this is a field that returns a string (since objects cannot be serialized)
        app = request.GET.get('app', 'undefined') # What app name?
        manager = request.GET.get('manager', 'undefined') # If a manager other than the defailt needed (ie, to return archived items)
        if app == 'undefined':
            TargetModel = apps.get_model('informant_lookups', model_class)
        else:
            TargetModel = apps.get_model(app, model_class)
        if search_follow == 'undefined' or search_follow is None:
            lookup = f"{search_field}__istartswith"
        else:
            lookup = f"{search_field}__{search_follow}__istartswith"
        #if manager == 'SYS':
        #    qs = TargetModel.objects_sys.all()
        #else:
        #    qs = TargetModel.objects.all()
        if manager == 'undefined':  # If a manager other than the default needed (ie to see archives)
            manager = 'objects'
        qs = getattr(TargetModel, manager).all()  # Like TargetModel.(variable manager).all()
        if term:
            qs = qs.filter(**{lookup: term})
        if filter_term != 'undefined' and filter_field != 'undefined':
            qs = qs.filter(**{filter_field: filter_term})
        if exclude_term != 'undefined' and exclude_field != 'undefined':
            exclude_terms = [x.strip() for x in exclude_term.split(',')]
            for ex_term in exclude_terms:
                qs = qs.exclude(**{exclude_field: ex_term})
        items = qs.order_by(search_field)
        results=[]
        for item in items:
            item_json = {}
            if ret_str != 'undefined' and ret_str is not None:  # ret_str is the name of a field that returns a string
                item_json['value'] = getattr(item, ret_str)   #getattr simulates item.search_field - use this since search field dynamic string
                item_json['label'] = getattr(item, ret_str)
                item_json['id'] = getattr(item, ret_str)
            else:
                item_json['value'] = getattr(item, search_field)   #getattr simulates item.search_field - use this since search field dynamic string
                item_json['label'] = getattr(item, search_field)
                item_json['id'] = getattr(item, search_field)
            if ret_value != 'undefined' and ret_value is not None:  #Use this if primary key is an id number and value is a string
                item_json['id'] = getattr(item, ret_value)
            results.append(item_json)
    else:
        results='fail'
    data = json.dumps(results)
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

#Get ID of item based on unique fields name, customer, cust_item_code
@deny_get
def get_item_id(request):
    item_name = request.POST.get('item_name', None)
    cust_item_code = request.POST.get('cust_item_code', None)
    customer = request.POST.get('customer', None)
    try:
        item_id = Item.objects.get(name=item_name, cust_item_code=cust_item_code, customer_id=customer).id
        data = {'id': item_id}
    except:
        data = {'id': 'not-found'}
    return JsonResponse(data)

@deny_get
def get_building(request):
    line_id = JobLog.objects.get(job=request.POST.get('job')).line_id
    site = request.site.id
    try:
        data = {'building': get_building_as_str(line_id, site),
                'found': True}
    except:
        data = {'building': 'not-found',
                'found': False}
    return JsonResponse(data)
