#!/usr/bin/env python3  
# -*- coding: utf-8 -*-  
"""
@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
@AUTHOR: ASJRD018
@NAME: langer
@software: PyCharm
@DATE: 2020/8/21 15:44
@Version: python3.6
@MODIFY DECORD:ansjer dev
"""
from var_dump import var_dump
import json
from django.http import HttpResponse

from django.views.generic import TemplateView
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from object.ResponseObject import ResponseObject
from django.contrib.auth.hashers import make_password, check_password
from model.models import UserModel, LangSetModel, LangAreaModel, LangKeyModel, LangValModel, LangPermModel, \
    SearchToolBlock, SearchToolKeyModel, LangLocationModel
import time
from object.TokenObject import TokenObject
from django.db.models import Q

class SearchToolView(TemplateView):
    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation', None)
        request_dict = json.loads(request.body.decode('utf-8'))
        return self.validate(request_dict, operation)

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        request_dict = request.GET
        operation = kwargs.get('operation', None)
        return self.validate(request_dict, operation)

    def validate(self, request_dict, operation):
        response = ResponseObject()
        if operation == 'add_single':
            return self.do_add_single(request_dict, response)
        elif operation == 'deleteAll':
            return self.do_delete_all(request_dict, response)
        else:
            token = request_dict.get('token', None)
            tko = TokenObject(token)
            if tko.code == 0:
                userID = tko.userID
                if operation == 'add':
                    return self.do_add(request_dict, response)
                elif operation == 'update':
                    return self.do_update(request_dict, response, userID)
                elif operation == 'delete':
                    return self.do_delete(request_dict, response)
                # search index table
                elif operation == 'query_context':
                    return self.do_query(request_dict, response, userID)
                elif operation == 'query_key':
                    return self.do_query_key(request_dict, response, userID)
                elif operation == 'query_location':
                    return self.do_query_location(request_dict, response, userID)
                elif operation == 'query_translation':
                    return self.do_query_translation(request_dict, response, userID)
                elif operation == 'query_saveOrEditKeyFrom':
                    return self.do_query_saveOrEditKeyFrom(request_dict, response)
                elif operation == 'query_saveOrEditLocationFrom':
                    return self.do_query_saveOrEditLocationFrom(request_dict, response)
                elif operation == 'query_saveOrEditTranslationFrom':
                    return self.do_query_saveOrEditTranslationFrom(request_dict, response, userID)
                elif operation == 'saveOrExitKey':
                    return self.do_saveOrExitKey(request_dict, response)
                elif operation == 'saveOrExitLocation':
                    return self.do_saveOrExitLocation(request_dict, response)
                elif operation == 'saveOrExitTranslation':
                    return self.do_saveOrExitTranslation(request_dict, response)
                elif operation == 'deleteKey':
                    return self.do_deleteKey(request_dict, response)
                elif operation == 'deleteLocation':
                    return self.do_deleteLocation(request_dict, response)
                elif operation == 'reset':
                    return self.do_reset(request_dict, response, userID)
                else:
                    return response.json(414)
            else:
                return response.json(tko.code)

    def do_add(self, request_dict, response):
        mokuainame = request_dict.get('name', None)
        type = request_dict.get('type', None)
        if not type:
            return response.json(444, 'type')

        lk = SearchToolBlock.objects.filter(name=mokuainame)
        if lk.exists():
            return response.json(404, repr("已存在模块名"))
        nowTime = int(time.time())
        try:
            SearchToolBlock.objects.create(name=mokuainame,type=type, addTime=nowTime, updTime=nowTime)
        except Exception as e:
            print(repr(e))
            return response.json(404, repr(e))
        else:
            return response.json(0)

    '''
    post_data = {
        word_key_id:1,
        word_key:xxx,
        word_arr:[
            {'lang':'','val':''},
            {'lang':'','val':''},   
            {'lang':'','val':''}
        ]
    }
    '''

    def do_update(self, request_dict, response, userID):
        mokuainame = request_dict.get('name', None)
        mokuaitype = request_dict.get('type', None)
        mokuaiid = request_dict.get('id', None)

        mk = SearchToolBlock.objects.filter(name=mokuainame)
        if mk.exists():
            return response.json(404, repr("已存在模块名"))

        lk = SearchToolBlock.objects.filter(id=mokuaiid)
        nowTime = int(time.time())
        if lk.exists():
            lk.update(updTime=nowTime,name=mokuainame)

            return response.json(0)
        else:
            return response.json(404)

    def do_delete(self, request_dict, response):
        print('delete')
        mokuaiid = request_dict.get('id', None)

        try:
            SearchToolBlock.objects.get(id=mokuaiid).delete()

        except Exception as e:
            return response.json(404, repr(e))
        else:
            return response.json(0)


    def do_query(self, request_dict, response, userID):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        searchKey = request_dict.get('searchKey', None)
        searchVal = request_dict.get('searchVal', None)
        type = request_dict.get('type', None)
        if searchKey:
            searchKey = searchKey.strip()
        if searchVal:
            searchKey = searchKey.strip()
        orderByupdate = request_dict.get('orderByupdate', 0)
        if page and line:
            search_qs = SearchToolBlock.objects.filter(type__contains=type).values('name', 'type', 'id','updTime')

            if type == 0:
                search_qs = SearchToolBlock.objects.filter(type__in=(0))
            elif type == 1:
                search_qs = SearchToolBlock.objects.filter(type__in=(1))

            if searchKey and searchVal:
                search_qs = search_qs.filter(name__contains=searchVal)



            count = search_qs.count()

            if orderByupdate == 1:
                search_qs = search_qs.order_by('updTime')
            else:
                search_qs = search_qs.order_by('-updTime')
            search_qs = search_qs[(page - 1) * line:page * line]

            k_list = []
            lw_dict = {}
            for lk in search_qs:
                k_list.append(lk['name'])
                lw_dict[lk['name']] = {'updTime': lk['updTime']}

            res = {
                'la_list': list(search_qs),
                'lw_dict': lw_dict,
                # 'lk_list': list(lk_qs),
                # 'lv_list': list(lv_qs)
                'count': count
            }
            return response.json(0, res)
        else:
            return response.json(444, 'page,line')

    def do_query_key(self, request_dict, response, userID):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        searchKey = request_dict.get('searchKey', None)
        searchVal = request_dict.get('searchVal', None)
        type = request_dict.get('type', None)
        if searchKey:
            searchKey = searchKey.strip()
        if searchVal:
            searchKey = searchKey.strip()
        orderByupdate = request_dict.get('orderByupdate', 0)
        if page and line:
            block_qs = SearchToolBlock.objects.filter(type__contains=type).values('id', 'name')
            k_list = []
            for bk in block_qs:
                k_list.append(bk['id'])

            search_qs = SearchToolKeyModel.objects.filter(bk__id__in=k_list).values('lk__id','lk__word_key','lk__updTime','bk__id','bk__name')

            #search_qs = LangKeyModel.objects.filter(id__in=k_list).values('id', 'word_key', 'updTime', 'project__id')


            if searchKey and searchVal:
                if searchKey == 'bk_name':
                    search_qs = search_qs.filter(bk__name__contains=searchVal)
                else :
                    search_qs = search_qs.filter(lk__word_key__contains=searchVal)


            count = search_qs.count()

            if orderByupdate == 1:
                search_qs = search_qs.order_by('lk__updTime')
            else:
                search_qs = search_qs.order_by('-lk__updTime')
            search_qs = search_qs[(page - 1) * line:page * line]

            lw_dict = {}
            for lk in search_qs:
                lw_dict[lk['lk__id']] = {'lk_id': lk['lk__id'], 'word_key': lk['lk__word_key'], 'updTime': lk['lk__updTime'],
                                     'bk_id': lk['bk__id'], 'name': lk['bk__name']}

            res = {
                'la_list': lw_dict,
                'count': count
            }
            return response.json(0, res)
        else:
            return response.json(444, 'page,line')

    def do_query_location(self, request_dict, response, userID):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        searchKey = request_dict.get('searchKey', None)
        searchVal = request_dict.get('searchVal', None)
        type = request_dict.get('type', None)
        if searchKey:
            searchKey = searchKey.strip()
        if searchVal:
            searchKey = searchKey.strip()
        orderByupdate = request_dict.get('orderByupdate', 0)
        if page and line:
            block_qs = SearchToolBlock.objects.filter(type=type).values('name', 'id', "searchtoolkeymodel__lk__id")
            k_list = []
            for bk in block_qs:
                k_list.append(bk['searchtoolkeymodel__lk__id'])
            lk_qs = LangKeyModel.objects.filter(id__in=k_list).values('id', 'word_key')
            k_list = []
            for lk in lk_qs:
                k_list.append(lk['id'])

            search_qs = LangLocationModel.objects.filter(lk__id__in=k_list).values('id','filename','line','lk__id','lk__word_key','lk__updTime')

            if searchKey and searchVal:
                if searchKey == "word_key":
                    search_qs = search_qs.filter(lk__word_key__contains=searchVal)
                elif searchKey == "filename":
                    search_qs = search_qs.filter(filename__contains=searchVal)
                elif searchKey == "line":
                    search_qs = search_qs.filter(line__contains=searchVal)

            count = search_qs.count()

            # if orderByupdate == 1:
            #     search_qs = search_qs.order_by('updTime')
            # else:
            #     search_qs = search_qs.order_by('-lk__updTime')
            # 根据 word_key 字母排序
            search_qs = search_qs.order_by('lk__word_key')
            search_qs = search_qs[(page - 1) * line:page * line]

            lw_dict = {}
            for lk in search_qs:
                lw_dict[lk['id']] = {'id': lk['id'], 'filename': lk['filename'], 'line': lk['line'], 'lk_id': lk['lk__id'], 'word_key': lk['lk__word_key']}

            res = {
                'la_list': lw_dict,
                'count': count
            }
            return response.json(0, res)
        else:
            return response.json(444, 'page,line')

    def do_query_translation(self, request_dict, response, userID):
        page = int(request_dict.get('page', None))
        line = int(request_dict.get('line', None))
        searchKey = request_dict.get('searchKey', None)
        searchVal = request_dict.get('searchVal', None)
        type = request_dict.get('type', None)
        if searchKey:
            searchKey = searchKey.strip()
        if searchVal:
            searchKey = searchKey.strip()
        orderByupdate = request_dict.get('orderByupdate', 0)
        if page and line:
            lang_set_list = LangSetModel.objects.filter(user__id=userID).values_list('lang__id', flat=True)
            lang_set_list = list(lang_set_list)
            la_qs = LangAreaModel.objects.filter(id__in=lang_set_list).values('lang', 'id')

            block_qs = SearchToolBlock.objects.filter(type=type).values('name', 'id', "searchtoolkeymodel__lk__id")
            k_list = []
            for bk in block_qs:
                k_list.append(bk['searchtoolkeymodel__lk__id'])
            lk_qs = LangKeyModel.objects.filter(id__in=k_list).values('id', 'word_key', 'updTime')

            if searchKey and searchVal:
                if searchKey == 'key':
                    lk_qs = lk_qs.filter(word_key__contains=searchVal)
                    # lk_qs = lk_qs.filter(word_key=searchVal)
                else:
                    lk_qs = lk_qs.filter(langvalmodel__word_val__contains=searchVal, langvalmodel__la__lang=searchKey)
            count = lk_qs.count()
            # lk_qs = lk_qs[(page - 1) * line:page * line].values_list('word_key', flat=True)

            if orderByupdate == 1:
                lk_qs = lk_qs.order_by('updTime')
            else:
                lk_qs = lk_qs.order_by('-updTime')
            lk_qs = lk_qs[(page - 1) * line:page * line]
            k_list = []
            lw_dict = {}
            for lk in lk_qs:
                k_list.append(lk['id'])
                lw_dict[lk['id']] = {'word_key': lk['word_key'], 'updTime': lk['updTime']}
            lv_qs = LangValModel.objects.filter(lk__id__in=k_list, la__id__in=lang_set_list). \
                values('word_val', 'la__id', 'la__lang', 'lk__word_key', 'lk__id', 'status')
            user = UserModel.objects.get(id=userID)
            lang_perm_ql = LangPermModel.objects.filter(user__id=userID).values_list('lang__lang', flat=True)
            lang_perm_ls = list(lang_perm_ql)

            for lv in lv_qs:
                lang = lv['la__lang']
                # print('lang=%s' % lang)
                lw_dict[lv['lk__id']][lang] = lv['word_val']
                if user.role_type == 1:
                    lw_dict[lv['lk__id']]['status'] = 0
                elif lang in lang_perm_ls:
                    lw_dict[lv['lk__id']]['status'] = lv['status']
            res = {
                'la_list': list(la_qs),
                'lw_dict': lw_dict,
                # 'lk_list': list(lk_qs),
                # 'lv_list': list(lv_qs)
                'count': count
            }
            return response.json(0, res)
        else:
            return response.json(444, 'page,line')


    def do_query_saveOrEditKeyFrom(self, request_dict, response):
       keyid = request_dict.get('keyid', None)
       type = request_dict.get('type', None)

       block_qs = SearchToolBlock.objects.filter(type=type).values('id', 'name')
       if keyid:
            search_qs = SearchToolKeyModel.objects.filter(lk__id=keyid).values('lk__id','lk__word_key','lk__updTime','bk__id','bk__name')
            lw_dict = {}
            for lk in search_qs:
                lw_dict[lk['lk__id']] = {'lk_id': lk['lk__id'], 'word_key': lk['lk__word_key'],
                                         'updTime': lk['lk__updTime'],
                                         'bk_id': lk['bk__id'], 'name': lk['bk__name']}
            res = {
                'la_list': lw_dict,
                'lw_dict': list(block_qs)

            }
            return response.json(0, res)
       else:

           res = {
               'lw_dict': list(block_qs)
           }
           return response.json(0, res)

    def do_query_saveOrEditLocationFrom(self, request_dict, response):
       locationid = request_dict.get('locationid', None)
       type = request_dict.get('type', None)

       block_qs = SearchToolBlock.objects.filter(type=type).values('name', 'id', 'searchtoolkeymodel__lk__id')
       k_list = []
       for bk in block_qs:
           k_list.append(bk['searchtoolkeymodel__lk__id'])
       lk_qs = LangKeyModel.objects.filter(id__in=k_list).values('id', 'word_key', 'updTime')
       #lk_qs = LangKeyModel.objects.filter(project_id=project_id).values('id', 'word_key')
       if locationid:
            search_qs = LangLocationModel.objects.filter(id=locationid).values('id','filename','line','lk__id','lk__word_key','lk__updTime')
            lw_dict = {}
            for lk in search_qs:
                lw_dict[lk['id']] = {'id': lk['id'], 'filename': lk['filename'], 'line': lk['line'], 'lk_id': lk['lk__id'], 'word_key': lk['lk__word_key']}
            res = {
                'la_list': lw_dict,
                'lw_dict': list(lk_qs)

            }
            return response.json(0, res)
       else:

           res = {
               'lw_dict': list(lk_qs)
           }
           return response.json(0, res)

    def do_query_saveOrEditTranslationFrom(self, request_dict, response, userID):
       valueid = request_dict.get('valueid', None)
       type = request_dict.get('type', None)

       # lk_qs = LangKeyModel.objects.filter(project_id=project_id).values('id', 'word_key')
       block_qs = SearchToolBlock.objects.filter(type=type).values('name', 'id', 'searchtoolkeymodel__lk__id')
       k_list = []
       for bk in block_qs:
           k_list.append(bk['searchtoolkeymodel__lk__id'])
       lk_qs = LangKeyModel.objects.filter(id__in=k_list).values('id', 'word_key', 'updTime')
       if valueid:
           lang_set_list = LangSetModel.objects.filter(user__id=userID).values_list('lang__id', flat=True)
           lang_set_list = list(lang_set_list)
           la_qs = LangAreaModel.objects.filter(id__in=lang_set_list).values('lang', 'id').order_by('id')

           # lk_qs = LangKeyModel.objects.filter(project_id=project_id).values('id', 'word_key', 'updTime')

           k_list = []
           lw_dict = {}
           for lk in lk_qs:
               k_list.append(lk['id'])
               lw_dict[lk['id']] = {'word_key': lk['word_key'], 'updTime': lk['updTime']}
           lv_qs = LangValModel.objects.filter(lk__id__in=k_list, la__id__in=lang_set_list). \
               values('word_val', 'la__id', 'la__lang', 'lk__word_key', 'lk__id', 'status')
           user = UserModel.objects.get(id=userID)
           lang_perm_ql = LangPermModel.objects.filter(user__id=userID).values_list('lang__lang', flat=True)
           lang_perm_ls = list(lang_perm_ql)
           for lv in lv_qs:
               lang = lv['la__lang']
               # print('lang=%s' % lang)
               lw_dict[lv['lk__id']][lang] = lv['word_val']
               if user.role_type == 1:
                   lw_dict[lv['lk__id']]['status'] = 0
               elif lang in lang_perm_ls:
                   lw_dict[lv['lk__id']]['status'] = lv['status']
           res = {
               'la_list': list(la_qs),
               'lw_dict': lw_dict,
               'lk_dict': list(lk_qs)
           }
           return response.json(0, res)
       else:

           res = {
               'lk_dict': list(lk_qs)
           }
           return response.json(0, res)

    def do_saveOrExitKey(self, request_dict, response):
        id  = request_dict.get('id', None)
        bk_id = request_dict.get('bk_id', None)
        word_key = request_dict.get('word_key', None)
        type = request_dict.get('type', None)
        project_id = request_dict.get('project_id', None)
        if not type:
            return response.json(444, 'type')

        nowTime = int(time.time())
        try:
            if id:
                update_dict = {
                    'word_key': word_key,
                    'updTime': nowTime
                }
                LangKeyModel.objects.filter(id=id).update(**update_dict)
                SearchToolKeyModel.objects.filter(lk__id=id).update(bk_id = bk_id )
            else:

             lkModel = LangKeyModel.objects.create(word_key=word_key, type=0, project_id=project_id, addTime=nowTime, updTime=nowTime)
             SearchToolKeyModel.objects.create(lk = lkModel, bk_id = bk_id)
        except Exception as e:
            print(repr(e))
            return response.json(404, repr(e))
        else:
            return response.json(0)

    def do_saveOrExitLocation(self, request_dict, response):
        id  = request_dict.get('id', None)
        filename = request_dict.get('filename', None)
        line = request_dict.get('line', None)
        lk_id = request_dict.get('lk_id', None)

        try:
            if id:
                update_dict = {
                    'filename': filename,
                    'line': line,
                    'lk_id' : lk_id
                }
                LangLocationModel.objects.filter(id=id).update(**update_dict )
            else:
                LangLocationModel.objects.create(filename=filename, line=line, lk_id=lk_id)

        except Exception as e:
            print(repr(e))
            return response.json(404, repr(e))
        else:
            return response.json(0)

    def do_saveOrExitTranslation(self, request_dict, response):
        id  = request_dict.get('id', None)
        lk_id = request_dict.get('lk_id', None)
        word_arr = request_dict.get('word_arr', None)
        nowTime = int(time.time())
        try:
            if id:
                for w in word_arr:
                    lm =LangValModel.objects.filter(lk__id=lk_id, la_id=w['la_id'])
                    if lm :
                        lm.delete()
                    LangValModel.objects.create(la_id=w['la_id'], lk_id=lk_id, addTime=nowTime, updTime=nowTime,
                                                word_val=w['val'], status=1)
            else:
                for w in word_arr:
                    LangValModel.objects.create(la_id=w['la_id'], lk_id=lk_id, addTime=nowTime, updTime=nowTime,
                                                word_val=w['val'], status=1)

        except Exception as e:
            print(repr(e))
            return response.json(404, repr(e))
        else:
            return response.json(0)

    def do_deleteKey(self, request_dict, response):
        print('delete')
        id = request_dict.get('id', None)

        try:
            LangKeyModel.objects.get(id=id).delete()

        except Exception as e:
            return response.json(404, repr(e))
        else:
            return response.json(0)


    def do_deleteLocation(self, request_dict, response):
        id = request_dict.get('id', None)
        try:
            LangLocationModel.objects.get(id=id).delete()

        except Exception as e:
            return response.json(404, repr(e))
        else:
            return response.json(0)

    def do_reset(self, request_dict, response, userID):

        return response.json(10,"数据已重置")

    def do_add_single(self, request_dict, response):
        word_class = request_dict.get('word_class', None)
        word_key = request_dict.get('word_key', None)
        word_array = request_dict.get('word_array', None)
        location_array = request_dict.get('location_array', None)

        if word_class and word_key and word_array and location_array:
            # SearchToolBlock
            # 检查是否已有该 name
            searchToolBlock_qs = SearchToolBlock.objects.filter(name=word_class)
            if searchToolBlock_qs.exists(): # 更新 updTime
                addTime = int(time.time())
                searchToolBlock_model = searchToolBlock_qs[0]
                searchToolBlock_model.updTime = addTime
                searchToolBlock_model.save()
            else:   # 插入新数据
                addTime = int(time.time())
                dataDict = {
                    'name' : word_class,
                    'type': '0',
                    'addTime': addTime,
                    'updTime': addTime,
                }
                searchToolBlock_model = SearchToolBlock.objects.create(**dataDict)
                dataDict.clear()

            # LangKeyModel,SearchToolKeyModel
            word_key = word_class + '_' + word_key  # 拼接word_class和word_key,避免word_key重复时写不进
            # 检查是否已有该 word_key
            langKey_qs = LangKeyModel.objects.filter(word_key=word_key)
            if langKey_qs.exists(): # 更新 updTime
                addTime = int(time.time())
                langKey_model = langKey_qs[0]
                langKey_model.updTime = addTime
                langKey_model.save()
            else:   # 插入新数据, 更新SearchToolKeyModel
                addTime = int(time.time())
                dataDict = {
                    'word_key': word_key,
                    'project_id': 4,
                    'type': 0,
                    'addTime': addTime,
                    'updTime': addTime,
                }
                langKey_model = LangKeyModel.objects.create(**dataDict)
                dataDict.clear()
                # SearchToolKeyModel.objects.create(bk_id=searchToolBlock_model.id, lk_id=langKey_model.id)
                SearchToolKeyModel.objects.create(bk=searchToolBlock_model, lk=langKey_model)

            # LangLocationModel
            locations = list(location_array)
            for location in locations:
                # 不更新ls,filename和line三者都相等的
                if not LangLocationModel.objects.filter(lk=langKey_model, filename=location['filename'], line=location['line']).exists():
                    dataDict = {
                        'lk': langKey_model,
                        'filename': location['filename'],
                        'line': location['line']
                    }
                    LangLocationModel.objects.create(**dataDict)
                    dataDict.clear()

            # LangValModel
            translations = list(word_array)
            for translation in translations:
                la_id = translation['la_id']
                langArea = LangAreaModel.objects.filter(id=la_id)[0]
                translationValue = translation['val']
                addTime = int(time.time())

                dataDict = {
                    'lk': langKey_model,
                    'la': langArea,
                    'word_val': translationValue,
                    'addTime': addTime,
                    'updTime': addTime,
                    'status': 1,
                }
                LangValModel.objects.create(**dataDict)
                dataDict.clear()

            return response.json(0)
        else:
            return response.json(444)

    def do_delete_all(self, request_dict, response):
        LangKeyModel.objects.filter(project__id=4).delete()
        return response.json(0)

