import itertools
import json
import os

from django.http import HttpResponse

from django.db.utils import IntegrityError

from django.contrib.sessions.backends.db import SessionStore

from .tesseract import convert_tiff_path_to_text
from .highlighter import convert_string_to_html
from .decisioner import HmsTreeGenerator
from .decisioner import Cursor
from ..models import UserComplaintClassification
from .cfpb_db import update_database
from .analyzer import classify


class AjaxFielder(object):
    '''Static methods for ajax requests.'''

    @classmethod
    def input_ajax(cls, request):
        '''Takes ajax request and routes data to the appropriate routine.'''
        # Delay makes animations look nicer.
        print(request.POST.dict())
        function_dict = {'load_tiff': cls.load_tiff,
                         'choice': cls.choice,
                         'backup': cls.backup,
                         'db_refresh': cls.db_refresh,
                         'analyze_tiff': cls.analyze_tiff,
                         'analyze_text': cls.analyze_text}
        try:
            function_string = request.POST.dict()['function']
            target_function = function_dict[function_string]
        except KeyError:
            return False
        result_list = target_function(request)
        return json.dumps(result_list)

    @classmethod
    def load_tiff(cls, request):
        '''Take a tiff, turn it into text, and return a response.'''
        response = {}
        sent_file = request.FILES['file']
        if sent_file.size > 10000000:
            return 'No files over 10 megabytes.'
        temporary_path = os.path.join(os.path.expanduser("~"),
                                      'hms_tempfile.tiff')
        with open(temporary_path, 'wb+') as f:
            f.write(sent_file.read())
        # Get text
        extracted_text = convert_tiff_path_to_text(temporary_path).decode()
        highlighted_text = convert_string_to_html(extracted_text)
        os.remove(temporary_path)
        # Store extracted and highlighted text in session.
        request.session['highlighted_text'] = highlighted_text
        request.session['extracted_text'] = extracted_text
        tree = HmsTreeGenerator().get_tree()
        request.session['decision_tree'] = tree
        request.session['cursor'] = Cursor(tree.get_root(),
                                           extracted_text)
        request.session.save()
        if extracted_text:
            panel_1_text = request.session['cursor'].get_node_criterion()
            panel_1_text += '<br><br>'
            for item in request.session['cursor'].get_node_options():
                panel_1_text += ''.join(['<button ',
                                         'class="btn btn-default" '
                                         'type="button" ',
                                         'onclick=call("choice",',
                                         '"',
                                         str(item),
                                         '"',
                                         '); ',
                                         'class="btn btn-default">',
                                         str(item),
                                         '</button>'])
                panel_1_text += '&nbsp;&nbsp;&nbsp;'
            response['#panel_1'] = panel_1_text
            response['#panel_2'] = highlighted_text
            sess = request.session
            response['#panel_3'] = sess['cursor'].get_node_description()
            response['#panel_4'] = sess['cursor'].get_tags()
        else:
            response['#panel_2'] = 'No text found'
        return response

    @classmethod
    def choice(cls, request):
        '''Takes a choice and response.'''
        choice_string = request.POST.dict()['arguments']
        choice = cls.string_to_class(choice_string)
        response = {}
        # Store extracted and highlighted text in session.
        cursor = request.session['cursor']
        cursor.choose(choice)
        # If cursor complete, write to database.
        if cursor.complete:
            tags = [item for item
                    in set(cursor.get_tags())
                    if item is not None]
            response['#panel_1'] = ' '
            response['#panel_3'] = ' '
            response['#panel_4'] = ' '
            response['#panel_2'] = 'Analysis complete. Tags:\n'
            response['#panel_2'] += '<br>'.join(tags)
            sans_tags = [item.replace('#','')
                         for item in tags]
            argument_dict = {key: True for key in sans_tags}
            UCC = UserComplaintClassification
            complaint = UCC(categorizer=request.user.username,
                            complaint_text=str(cursor._inspected_item_data),
                            tag_string=''.join(tags),
                            **argument_dict)
            complaint.save()

        else:
            panel_1_text = cursor.get_node_criterion()
            panel_1_text += '<br><br>'
            for item in cursor.get_node_options():
                panel_1_text += ''.join(['<button ',
                                         'class="btn btn-default" '
                                         'type="button" ',
                                         'onclick=call("choice",',
                                         '"',
                                         str(item),
                                         '"); ',
                                         'class="btn btn-default">',
                                         str(item),
                                         '</button>'])
                panel_1_text += '&nbsp;&nbsp;&nbsp;'
            panel_1_text += '<br><br>'
            panel_1_text += '<button class="btn btn-default" type="button" '
            panel_1_text += 'onclick=call("backup","");>Backup</button>'
            response['#panel_1'] = panel_1_text
            response['#panel_3'] = cursor.get_node_description()
            tags = [item for item
                    in set(cursor.get_tags())
                    if item is not None]
            print(tags)
            response['#panel_4'] = '<br>'.join(tags)
        # request.session['cursor'] = cursor
        request.session.save()
        return response

    @classmethod
    def string_to_class(cls, input_string):
        stripped_string = input_string.strip()
        if stripped_string == 'True':
            return True
        if stripped_string == 'False':
            return False
        try:
            float(stripped_string)
            if '.' in input_string:
                return float(input_string)
            else:
                return int(input_string)
        except ValueError:
            return input_string

    @classmethod
    def backup(cls, request):
        response = {}
        # Store extracted and highlighted text in session.
        cursor = request.session['cursor']
        cursor.backup()
        panel_1_text = cursor.get_node_criterion()
        panel_1_text += '<br><br>'
        for item in cursor.get_node_options():
            panel_1_text += ''.join(['<button ',
                                     'class="btn btn-default" '
                                     'type="button" ',
                                     'onclick=call("choice",',
                                     '"',
                                     str(item),
                                     '"); ',
                                     'class="btn btn-default">',
                                     str(item),
                                     '</button>'])
            panel_1_text += '&nbsp;&nbsp;&nbsp;'
        # If can back up further, add backup button
        if cursor._current_node.parent_node is not None:
            panel_1_text += '<br><br>'
            panel_1_text += '<button class="btn btn-default" type="button" '
            panel_1_text += 'onclick=call("backup","");>Backup</button>'
        response['#panel_1'] = panel_1_text
        response['#panel_3'] = cursor.get_node_description()
        tags = [item for item
                in set(cursor.get_tags())
                if item is not None]
        response['#panel_4'] = '<br>'.join(tags)
        # request.session['cursor'] = cursor
        request.session.save()
        return response

    @classmethod
    def db_refresh(cls, request):
        response = {}
        # db_successfully_created is a boolean response
        db_successfully_created = update_database()
        if db_successfully_created:
            response["db_response_plan"] = "Successfully created."
            return response
        else:
            response["db_response_plan"] = "Failure."
            return response

    @classmethod
    def analyze_tiff(cls, request):
        text = cls.tiff_to_text(request)
        response = classify(text)
        # Response here
        return response

    @classmethod
    def tiff_to_text(cls, request):