# -*- coding:utf-8 -*-
"""问卷调查结果数据处理"""

from kyger.utility import numeric, str_replace, json2dict,date as date_time,dict2json_file


class Researchresult(object):
    """问卷调查结果调用"""
    __page = 0  # 当前页
    __total_page = 0  # 总页数
    __total_rows = 0  # 总记录数

    # 构造函数
    def __init__(self, db=None, kg=None):
        # 数据库
        from kyger.db import MySQL
        self.db = db if db else MySQL()  # 数据库操作对象
        self.kg = kg  # 全局变量

    def analysis(self, questionid, topic):
        """
        处理问卷题目,统计问卷结果
        questionid [int]|[str] 问卷id
        topic [int] 问题id
        return [list] 问卷题目分析结果, `{pr}question_result` as b
        """
        # page:调用第几页数据
        page = numeric(self.kg['get'].get('page', 1), 1)
        # 问卷id
        questionid = numeric(questionid)
        topic = numeric(topic)

        # 问卷下问题列表
        res = self.db.list(
            table='survey_question',
            field='*',
            where='`ques_id`=%d' % questionid,
            order='`sort` ASC'
        )
        # 问卷下是否有问题
        if res:
            # 要实现分页功能,当题目类型为填空类型时需要分页显示
            # 统计总人数,在分页之前统计总人数
            where = '`webid`=%d && `state`=%d && `questionid`=%d && `topicid`=%d' % (self.kg['web']['id'], 0, questionid, topic)
            count = self.db.list(
                table="question_result",
                field='type',
                where=where
            )
            # 人数
            countnum = len(count)
            # 判断题型是否分页
            flag = 0
            limit = 10
            for m in res:
                # 填空类型
                if m['id'] == topic and m['type'] in [2, 3, 4, 14, 15, 21]:
                    flag = 1
                    if m['type'] in [4, 15]:
                        limit = 1
                    break
            page_html = ''
            # 分页
            if flag:
                # 问题答案列表
                result = self.db.list(
                    table="question_result",
                    field='answer',
                    where=where,
                    page=page,
                    limit=limit
                )
                if page and page > self.db.total_page:
                    page = self.db.total_page
                    result = self.db.list(
                        table="question_result",
                        field='answer',
                        where=where,
                        page=page,
                        limit=limit
                    )
                from kyger.common import page_tpl
                page_html = page_tpl(self.db.page, self.db.total_page, 10, self.kg['server'].get('WEB_URL'))  # 获取分页模板
                total_rows = self.db.total_rows  # 总记录数
                total_page = self.db.total_page  # 总页数

                page_html = page_html
                page_data = {'page': page, 'total_page': total_page, 'total_rows': total_rows}

            else:
                # 问题答案列表
                result = self.db.list(
                    table="question_result",
                    field='answer',
                    where=where
                )
            # 查询到有用户完成答卷
            if result:
                # 答卷分析
                return page_html, self.ana_answer(res, topic, countnum, result, page)
            else: return "", {}
        else:return "", {}

    def list_page(self, *args, **kwargs):
        """
        分页获取问卷信息，参数同list。
        :return:{
            'list':          # 分页的当前页问卷数据
            'page_html':     # 分页的html模板
            'page_data':     # 分页的数据：当前页、总页数、总记录数
        }
        """

        # page和row的数据
        if self.kg['get'].get('page',1) != 1:
            self.__page = numeric(self.kg['get'].get('page', 1), 1)
        else:
            self.__page = numeric(self.kg['post'].get('page', 1), 1)  # 当前页
        if 'row' in kwargs: row = kwargs['row']  # 在kwargs里
        elif len(args) > 2: row = args[0]  # 在args里
        else: row = 10  # 默认10

        topic = ''
        if "topic" in kwargs:
            topic = kwargs['topic']
            # 实际数据量 = 每页显示数据*该问卷题目数量
            row = row*len(topic)

        # 获取问卷数据
        data = self.list(*args, **kwargs)
        # 分页模板合成
        web_url = self.kg['server'].get('WEB_URL')
        from kyger.common import page_tpl
        page_html = page_tpl(self.db.page, self.db.total_page, row, web_url)  # 获取分页模板
        print(page_html)
        self.__total_rows = self.db.total_rows  # 总记录数
        self.__total_page = self.db.total_page  # 总页数
        print(self.__total_page)
        if self.__total_page < 2:
            page_html = ""
        return {
            'list': data,
            'page_html': page_html,
            'page_data': {'page': self.__page, 'total_page': self.__total_page, 'total_rows': self.__total_rows}
        }

    # 已删除参数
    def list(self, row=10,start=0, topic=[], word='', ques_id=0, userid=0, date='%Y-%m-%d %H:%M:%S'):
        """
        获取问卷数据
        :param row: [int] 分页时为每页要显示的数量，不分页时为调用的总记录数。缺省值为 10
        :param start: [int] 不分页时，从第几天数据开始调用，分页时无效。缺省值0
        :param word: [str] 搜索的关键字。
        :param ques_id: [int] 问卷id。必须参数
        :param userid: [int] 是否开启验证用户,0不开启,1开启。开启则获取的数据只是当前用户提交的问卷
        
        :return:[list]
        """

        ques_id = numeric(ques_id)

        if ques_id == 0:
            return []

        if topic:
            # 实际数据量 = 每页显示数据*该问卷题目数量
            row = row*len(topic)
        else:
            return []
        # ************************************************************ where条件的处理
        # word_sql = "&& (`title` like '%%%s%%' or `description` like '%%%s%%')" % (word, word) if word else ""

        # 拼接where参数
        if userid != 0:
            where = "webid=%s && kgid=%s && questionid=%d" % (self.kg['web']['id'], self.kg['user']['id'], ques_id)
        else:
            where = "webid=%s && `questionid`=%d" % (self.kg['web']['id'], ques_id)
        # limit
        limit = row if self.__page else '%d, %d' % (start, row)

        data = self.db.list(
            table='question_result',
            where=where,
            order='addtime DESC',
            page=self.__page,
            limit=limit
        )
        if self.__page and self.__page > self.db.total_page:
            self.__page = self.db.total_page
            data = self.db.list(
                table='question_result',
                where=where,
                order='addtime DESC',
                page=self.__page,
                limit=limit
            )

        data = self.data_format(data, row, topic, date) if data else []  # 数据整形
        return data

    # **************************************************日期时间格式化处理
    def data_format(self, data, row, topic_list, date_format):
        """
        将数据进行整形
        :param data: [list{}] 从数据库查出的数据,答案列表
        :param row: [int] 整形成row条数据
        :param topic: [list] 问卷题目列表
        :param date_format: [str] 日期格式化：
                                %y 两位数的年份表示（00-99）  %Y 四位数的年份表示（000-9999）  %m 月份（01-12）  %d 日，月内中的一天（0-31）
                                %H 24小时制小时数（0-23）  %I 12小时制小时数（01-12）  %M 分钟数（00=59）  %S 秒（00-59）
                                %a 本地简化星期名称  %A 本地完整星期名称 %b 本地简化的月份名称, 英文  %B 本地完整的月份名称, 英文
                                %c 本地相应的日期表示和时间表示  %j 年内的一天（001-366）  %p 本地A.M.或P.M.的等价符  %U 一年中的星期数（00-53）星期天为星期的开始（第n周）
                                %w 星期（0-6），星期天为星期的开始  %W 一年中的星期数（00-53）星期一为星期的开始（第n周）   %x 本地相应的日期表示
                                %X 本地相应的时间表示  %Z 当前时区的名称  %% %号本身
        :return: [list{}] 将整形过后的数据返回
        """
        # print("分页之后的答案data:", data)
        # 答案时间列表
        addtime = []
        for i in data:
            if ['%s' % i['kgid'], '%s' % i['addtime']] not in addtime:
                addtime.append(['%s' % i['kgid'], '%s' % i['addtime']])
        # print('addtime:',addtime)
        result = []
        # 校验数据是否正确
        # print("len(addtime),row:",len(addtime), row)
        # print('问卷下所有题目结构:', topic_list)
        # if len(addtime) == row:
        # 每页显示的数据条数(每人的答案一行数据)
        for i in addtime:
            mid = {}
            mid['addtime'] = date_time(i[1], date_format)
            mid['answer'] = lis = []
            # 遍历答案
            for j in data:
                dic = {}
                # 符合某个用户某次答卷的所有答案
                if i and j['kgid'] == numeric(i[0]) and j['addtime'] == numeric(i[1]):

                    # 查询该题目结构
                    nginx = {}
                    for p in topic_list:
                        if p['id'] == j['topicid']:
                            nginx = p
                    if not nginx:
                        return []
                    # 类型
                    dic['type'] = json2dict(nginx['type'])
                    # 选项
                    if j['type'] == 2:
                        dic['options'] = options = [nginx['title']]
                    elif j['type'] == 14:
                        # 横向填空
                        a = json2dict(nginx['options'])['title']['name']
                        res = a.replace(' ', '').splitlines()
                        for k in range(len(res)):
                            if res[k]:
                                res[k] = res[k].replace('_', '').split(':')
                        dic['options'] = options = [j for i in res if i for j in i if j]
                    else:
                        dic['options'] = options = json2dict(nginx['options'])['title']
                    # 设置
                    dic['topic'] = topic = json2dict(nginx['topic'])

                    # 答案
                    answer = json2dict(j['answer'])
                    # 单选题 多选
                    if j['type'] in (0, 1, 9, 10):
                        # print("选项", options)
                        # print('答案', answer)
                        if j['answer']:
                            a = ''
                            for k in range(len(answer)):
                                if len(answer) < 2:
                                    a += '%s' % options[answer[k]]['name']
                                else:
                                    if k == 0:
                                        a += '%s' % options[answer[k]]['name']
                                    else:
                                        a += '|%s' % options[answer[k]]['name']
                            dic['result'] = a
                        else:
                            dic['result'] = []
                    # # 单项填空题 多项填空
                    # elif j['type'] in (2, 3):
                    #     dic['result'] = json2dict(j['answer'])
                    # 矩阵填空 矩阵打分
                    elif j['type'] in (2, 3, 4, 7, 8, 13, 14, 16, 17, 18, 19, 20,21,22,23):
                        dic['result'] = json2dict(j['answer'])
                    elif j['type'] == 15:
                        # 自增表格
                        dic['result'] = json2dict(j['answer'])
                        for ok in range(len(options)):
                            if options[ok]['type'] == 1:
                                for uu in range(len(dic['result'])):
                                    dic['result'][uu][ok] = options[ok]['select'][dic['result'][uu][ok]]

                    elif j['type'] in (5, 12):
                        # 矩阵选择
                        a = []
                        for kk in range(len(answer)):
                            if answer[kk]:
                                b = ''
                                for k1 in range(len(answer[kk])):
                                    if len(answer[kk]) < 2:
                                        if j['type'] == 12:
                                            b += options['opt'][answer[kk][k1]]['name']
                                        else:
                                            b += options['x'][answer[kk][k1]]
                                    else:
                                        if k1 == 0:
                                            if j['type'] == 12:
                                                b += options['opt'][answer[kk][k1]]['name']
                                            else:
                                                b += options['x'][answer[kk][k1]]
                                        else:
                                            if j['type'] == 12:
                                                b += "|%s" % options['opt'][answer[kk][k1]]['name']
                                            else:
                                                b += "|%s" % options['x'][answer[kk][k1]]
                                a.append(b)
                        dic['result'] = a
                    elif j['type'] == 11:
                        pass
                        # # 级联题
                        # aa = ''
                        # lens = len(answer)
                        # if lens == 3:
                        #     if options[answer[0]]:
                        #         aa += options[answer[0]]['name']
                        #         if options[answer[0]]['city']:
                        #             aa += options[answer[0]]['city'][answer[1]]['name']
                        #             if options[answer[0]]['city'][answer[1]]['area']:
                        #                 aa += options[answer[0]]['city'][answer[1]]['area'][answer[2]]['name']
                        #                 if options[answer[0]]['city'][answer[1]]['area'][answer[2]]['town']:
                        #                     aa += options[answer[0]]['city'][answer[1]]['area'][answer[2]]['town']['name']
                        # dic['result'] = aa
                    lis.append(dic)
            result.append(mid)
        return result
        # return []

    # def single(self, questionnaire_id, userid=0, date='%Y-%m-%d %H:%M:%S'):
    #     """
    #     根据单个id获取数据
    #     :param questionnaire_id: [int] 要获取数据的ID
    #     :param date: [str] 日期格式化：
    #                             %y 两位数的年份表示（00-99）  %Y 四位数的年份表示（000-9999）  %m 月份（01-12）  %d 日，月内中的一天（0-31）
    #                             %H 24小时制小时数（0-23）  %I 12小时制小时数（01-12）  %M 分钟数（00=59）  %S 秒（00-59）
    #                             %a 本地简化星期名称  %A 本地完整星期名称 %b 本地简化的月份名称, 英文  %B 本地完整的月份名称, 英文
    #                             %c 本地相应的日期表示和时间表示  %j 年内的一天（001-366）  %p 本地A.M.或P.M.的等价符  %U 一年中的星期数（00-53）星期天为星期的开始（第n周）
    #                             %w 星期（0-6），星期天为星期的开始  %W 一年中的星期数（00-53）星期一为星期的开始（第n周）   %x 本地相应的日期表示
    #                             %X 本地相应的时间表示  %Z 当前时区的名称  %% %号本身
    #     :return: [list{}] 返回查询到的单条数据
    #     """
    #     # 转换成数值
    #     questionnaire_id = numeric(questionnaire_id, 0)
    #
    #     if userid != 0:
    #         # where
    #         where = 'webid=%s && recycle=0 && id=%s && kgid=%s' % (self.kg['web']['id'], questionnaire_id, self.kg['user']['id'])
    #     else:
    #         # where
    #         where = 'webid=%s && recycle=0 && id=%s' % (self.kg['web']['id'], questionnaire_id)
    #
    #     # 数据库查询与数据整形
    #     data = self.db.list(table='questionnaire', where=where, shift=1)
    #     if data: data = self.data_format(data, date)
    #     return data

    def ana_answer(self, res,topic,countnum,result, page):
        """
        处理每个题型的答案
        @param res:问卷下问题列表
        @param topic:目标问题id
        @param countnum:该问题回答人数
        @param result:该问题所有答案
        @param page:
        @return:整理后的数据

        """
        # 存放问卷某个问题的答卷结果
        results = []

        # 遍历问题
        for i in res:
            i["topic"] = json2dict(i["topic"])
            i["options"] = json2dict(i["options"])
            i["jump_logic"] = json2dict(i["jump_logic"])
            i["show_logic"] = json2dict(i["show_logic"])

            if i['id'] == topic:
                data = {}
                # 题号
                data['sort'] = i['sort'] + 1
                # 題型
                data['type'] = i['type']
                # 标题
                data['title'] = i['title']
                # 人数
                data['number'] = countnum if page else len(result)
                # 矩阵填空 矩阵选择 矩阵打分 矩阵评价
                if i['type'] in [4, 5, 22, 23]:
                    # 矩阵结构{"span": 2, "span1": "非常不满意", "span2": "非常满意", "start": 1, "style": 0, "max_num": 5

                    if i['type'] == 23:
                        data['options'] = [k+i['topic']['start'] for k in range(i['topic']['max_num']) ]
                    else:
                        data['options'] = i['options']['title']['x']
                    data['row'] = i['options']['title']['y']
                    # 答案
                    if i['type'] == 5:
                        cat = data['options']
                        opt = data['row']
                        ccc = []
                        for k in range(len(cat)):
                            cc = []
                            for f in result:
                                d = json2dict(f['answer'])
                                for m in range(len(d[k])):
                                    cc.append(d[k][m])
                            ccc.append(cc)
                        r = []
                        for op in range(len(opt)):
                            lin = []
                            for ca in range(len(ccc)):
                                lin.append(ccc[op].count(ca))
                            r.append(lin)
                        data['result'] = r
                    elif i['type'] == 4:
                        data['result'] = json2dict(result[0]['answer'])
                    else:
                        cc = []
                        for j in range(len(data['row'])):
                            bb = []
                            for k in range(len(data['options'])):
                                bb.append(0)
                            cc.append(bb)
                        if i['type'] == 22:
                            for m in result:
                                tt = json2dict(m['answer'])
                                for x in range(len(tt)):
                                    for y in range(len(tt[x])):
                                        cc[x][y] += tt[x][y] + 1
                            for q in range(len(cc)):
                                for s in range(len(cc[q])):
                                    cc[q][s] = cc[q][s]/countnum
                        else:
                            for m in result:
                                tt = json2dict(m['answer'])
                                for x in range(len(tt)):
                                    for y in range(len(tt[x])):
                                        cc[x][tt[x][y]] += 1
                        data['result'] = cc
                # 级联题
                elif i['type'] == 11:
                    pass
                # 分类题
                elif i['type'] == 12:
                    cat = i['options']['title']['cat']
                    opt = i['options']['title']['opt']
                    # 选项
                    data['options'] = [k['name'] for k in cat]
                    data['row'] = [k['name'] for k in opt]

                    ccc = []
                    for k in range(len(cat)):
                        cc = []
                        for f in result:
                            d = json2dict(f['answer'])
                            for m in range(len(d[k])):
                                cc.append(d[k][m])
                        ccc.append(cc)
                    r = []
                    for op in range(len(opt)):
                        lin = []
                        for ca in ccc:
                            lin.append(ca.count(op))
                        r.append(lin)
                    data['result'] = r

                # 单选 多选题 图片选择 图片投票 文字投票 下拉题 量表题 评价题 比重题
                if i['type'] in [0, 1, 7, 8, 9, 10, 13, 16, 20]:
                    # 选项
                    if i['type'] == 13:
                        data['options'] = [j + i['topic']['startnum'] for j in range(i['topic']['grade'])]
                    elif i['type'] in [16, 20]:
                        data['options'] = [j['title'] for j in i['options']['title']]
                    else:
                        data['options'] = [j['name'] for j in i['options']['title']]
                    # 答案
                    res_list = []
                    # 选项个数
                    length = len(data['options'])
                    # 所有答案
                    if i['type'] == 20:
                        for p in range(length):
                            answer = []
                            for k in result:
                                answer.append(json2dict(k['answer'])[p])
                            res_list.append(int(sum(answer) / length))
                    else:
                        answer = []
                        for k in result:
                            answer += map(lambda x: numeric(x), json2dict(k['answer']))
                        for l in range(length):
                            res_list.append(answer.count(l))

                    data['result'] = res_list
                    # 饼图
                    data['pie'] = []
                    for m in range(length):
                        pie_ = dict()
                        pie_['value'] = data['result'][m]
                        pie_['name'] = data['options'][m]
                        data['pie'].append(pie_)
                # 单项填空 多项填空 横向填空 自增表格 文件上传
                elif i['type'] in [2, 3, 14, 15, 21]:
                    # 选项
                    if i['type'] in [2, 21]:
                        data['options'] = [i['title']]
                    elif i['type'] == 3:
                        data['options'] = i['options']['title']
                    elif i['type'] == 14:
                        a = i['options']['title']['name']
                        lis = str_replace(a, [' ', '_', '\n'], ['', '', '']).split(":")
                        data['options'] = [row for row in lis if row]
                    elif i['type'] == 15:
                        data['options'] = [j['title'] for j in i['options']['title']]
                    # 答案
                    if i['type'] == 15:
                        r = [j for i in result for j in json2dict(i['answer'])]
                        for k in r:
                            for m in range(len(k)):
                                if i['options']['title'][m]['type'] == 1:
                                    k[m] = i['options']['title'][m]['select'][k[m]]
                        data['result'] = r
                    else:
                        data['result'] = [json2dict(i['answer']) for i in result]
                # 打分题 排序题
                elif i['type'] in [17, 19]:
                    # 选项列数
                    if i['type'] == 19:
                        data['options'] = ["第%s位" % (j + 1) for j in range(len(i['options']['title']))]
                        length = len(i['options']['title'])
                    else:
                        data['options'] = ['%s分' % (j + 1) for j in range(i['topic']['length'])]
                        length = i['topic']['length']
                    # 选项行数
                    data['row'] = [row['title'] for row in i['options']['title']]
                    res_list = []
                    # 先遍历选项,每次再把答案整出来
                    for h in range(len(i['options']['title'])):
                        e = []
                        # 所有答案
                        answer = []
                        for k in result:
                            answer.append(numeric(json2dict(k['answer'])[h]))
                        for l in range(length):
                            e.append(answer.count(l))
                        res_list.append(e)
                    data['result'] = res_list
                # nps题固定题型
                elif i['type'] == 18:
                    # 选项
                    data['options'] = ['批评型', '被动型', '推荐型', '净推荐分数Net Promoter® Score']
                    # 答案
                    answer = [numeric(j['answer']) for j in result]
                    # 人数
                    length = len(answer)
                    # 被动型
                    b1 = answer.count(7)
                    b2 = answer.count(8)
                    b = b1 + b2
                    # 推荐型
                    t1 = answer.count(9)
                    t2 = answer.count(10)
                    t = t1 + t2
                    # 批评型
                    p = length - b - t
                    # 净推荐分数
                    nps = t / length - p / length
                    data['result'] = [p, b, t, '%.2f' % (nps * 100)]
                results.append(data)
        return results








