
'use strict';

const Service = require('egg').Service;
const R = require('ramda');
const _ = require('lodash');
const moment = require('moment');

class ReportService extends Service {
  // 获取问题列表
  async getQuestionList(catId) {
    const { ctx } = this;

    // 获取用户宝宝年龄段
    const userBabyInfo = await ctx.classModel.V5.CourseV5UserBaby.findOne({ where: { user_uuid: ctx.userUuid, status: 1, is_deleted: 0 } });
    if (ctx.isEmpty(userBabyInfo) || ctx.isEmpty(userBabyInfo.baby_age)) {
      ctx.failed('请先选择您的宝宝年龄');
    }

    const questionList = await ctx.classModel.V5.CourseV5Question.findAll({ where: { cat_id: catId, age_id: userBabyInfo.baby_age, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ]] });
    if (ctx.isEmpty(questionList)) {
      return { list: [] };
    }

    // 获取所有选项
    let answerList = await ctx.classModel.V5.CourseV5Answer.findAll({ where: { question_id: { $in: _.uniq(R.pluck('id', questionList)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'question_id', 'title', 'sub_title', 'selected_icon', 'unselected_icon' ], order: [[ 'sort', 'asc' ]] });
    answerList = _.groupBy(answerList, 'question_id');

    const results = [];
    let number = 1;
    for (const v of questionList) {
      results.push({
        id: v.id,
        number: number++,
        cat_id: v.cat_id,
        title: v.title,
        style: v.style,
        type: v.type,
        answer: ctx.isEmpty(answerList[v.id]) ? [] : answerList[v.id],
      });
    }

    const ret = {
      list: results,
    };

    return ret;
  }

  // 生成报告
  async generateReport(input) {
    const { ctx } = this;
    const data = eval(input.data);

    // 校验cat_id
    const category = await ctx.classModel.V5.CourseV5Category.findOne({ where: { id: input.cat_id } });
    if (ctx.isEmpty(category) || category.type !== 3) {
      ctx.failed('cat_id error');
    }

    let answerIds = [];
    for (const v of data) {
      answerIds = _.concat(answerIds, v.answers);
    }
    const answerToReportColumnDetailList = await ctx.classModel.V5.CourseV5AnswerToReportColumnDetail.findAll({ where: { answer_id: { $in: answerIds }, status: 1, is_deleted: 0 }, attributes: [ 'report_column_detail_id' ] });
    const reportColumnDetailIds = _.uniq(R.pluck('report_column_detail_id', answerToReportColumnDetailList));

    const result = {
      user_uuid: ctx.userUuid,
      cat_id: input.cat_id,
      report_column_detail_ids: JSON.stringify(reportColumnDetailIds),
      answer: input.data,
    };
    const userReport = await ctx.classModel.V5.CourseUserReport.findOne({ where: { user_uuid: ctx.userUuid, cat_id: input.cat_id, status: 1, is_deleted: 0 } });
    if (ctx.isEmpty(userReport)) {
      await ctx.classModel.V5.CourseUserReport.findOrCreate({ where: { user_uuid: ctx.userUuid, cat_id: input.cat_id, status: 1, is_deleted: 0 }, defaults: result });
    } else {
      await ctx.classModel.V5.CourseUserReport.update({ is_deleted: 1 }, { where: { user_uuid: ctx.userUuid, cat_id: input.cat_id, status: 1, is_deleted: 0 } });
      await ctx.classModel.V5.CourseUserReport.findOrCreate({ where: { user_uuid: ctx.userUuid, cat_id: input.cat_id, status: 1, is_deleted: 0 }, defaults: result });
    }

    const report = await this.getReportByCategory(input.cat_id);
    return report;
  }

  // 获取报告详情
  async getReportByCategory(catId) {
    const { ctx } = this;

    const userReportInfo = await ctx.classModel.V5.CourseUserReport.findOne({ where: { user_uuid: ctx.userUuid, cat_id: catId, status: 1, is_deleted: 0 } });
    if (ctx.isEmpty(userReportInfo)) {
      ctx.failed('尚未生成报告');
    }

    const category = await ctx.classModel.V5.CourseV5Category.findOne({ where: { id: userReportInfo.cat_id }, attributes: [ 'id', 'name', 'url', 'color' ] });
    const userBabyInfo = await ctx.classModel.V5.CourseV5UserBaby.findOne({ where: { user_uuid: userReportInfo.user_uuid, status: 1, is_deleted: 0 }, attributes: [ 'user_uuid', 'baby_sex', 'baby_name', 'baby_age' ] });
    // 获取年龄对应的报告选项
    const ageToReport = await ctx.classModel.V5.CourseV5AgeToReportColumnDetail.findAll({ where: { age_id: userBabyInfo.baby_age, cat_id: userReportInfo.cat_id, status: 1, is_deleted: 0 } });
    const ageReportColumnDetailList = await ctx.classModel.V5.CourseV5ReportColumnDetail.findAll({ where: { id: { $in: _.uniq(R.pluck('report_column_detail_id', ageToReport)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'report_column_id', 'sub_title', 'level', 'content', 'advice' ], raw: true });

    let reportColumnDetailList = ctx.isEmpty(userReportInfo.report_column_detail_ids) ? [] : await ctx.classModel.V5.CourseV5ReportColumnDetail.findAll({ where: { id: { $in: eval(userReportInfo.report_column_detail_ids) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'report_column_id', 'sub_title', 'level', 'content', 'advice' ], raw: true });
    reportColumnDetailList = _.concat(reportColumnDetailList, ageReportColumnDetailList);
    const reportColumnList = await ctx.classModel.V5.CourseV5ReportColumn.findAll({ where: { id: { $in: _.uniq(R.pluck('report_column_id', reportColumnDetailList)) } }, order: [[ 'sort', 'asc' ]], attributes: [ 'id', 'title' ], raw: true });
    reportColumnDetailList = _.groupBy(reportColumnDetailList, 'report_column_id');

    const report = [];
    for (const v of reportColumnList) {
      report.push({
        id: v.id,
        title: v.title,
        value: ctx.isEmpty(reportColumnDetailList[v.id]) ? [] : reportColumnDetailList[v.id],
      });
    }

    const tags = await this.getReportTags(userReportInfo);
    const recommendClassList = await this.getRecommendClassListByReport(userReportInfo.answer, userReportInfo.user_uuid, userReportInfo.cat_id);

    const userQuestionnaire = await ctx.classModel.V5.CourseV5Questionnaire.findOne({ where: { user_uuid: userReportInfo.user_uuid, cat_id: userReportInfo.cat_id } });

    const ret = {
      id: userReportInfo.id,
      category: ctx.isEmpty(category) ? {} : category,
      has_questionnaire: ctx.isEmpty(userQuestionnaire) ? 0 : 1,
      tags,
      report,
      user: userBabyInfo,
      recommend_class_list: recommendClassList,
    };

    return ret;
  }

  async getReportById(reportId) {
    const { ctx } = this;

    const userReportInfo = await ctx.classModel.V5.CourseUserReport.findOne({ where: { id: reportId, status: 1, is_deleted: 0 }, raw: true });
    if (ctx.isEmpty(userReportInfo)) {
      ctx.failed('尚未生成报告');
    }

    const category = await ctx.classModel.V5.CourseV5Category.findOne({ where: { id: userReportInfo.cat_id }, attributes: [ 'id', 'name', 'url', 'color' ] });
    const userBabyInfo = await ctx.classModel.V5.CourseV5UserBaby.findOne({ where: { user_uuid: userReportInfo.user_uuid, status: 1, is_deleted: 0 }, attributes: [ 'user_uuid', 'baby_sex', 'baby_name', 'baby_age' ] });
    // 获取年龄对应的报告选项
    const ageToReport = await ctx.classModel.V5.CourseV5AgeToReportColumnDetail.findAll({ where: { age_id: userBabyInfo.baby_age, cat_id: userReportInfo.cat_id, status: 1, is_deleted: 0 } });
    const ageReportColumnDetailList = await ctx.classModel.V5.CourseV5ReportColumnDetail.findAll({ where: { id: { $in: _.uniq(R.pluck('report_column_detail_id', ageToReport)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'report_column_id', 'sub_title', 'level', 'content', 'advice' ], raw: true });

    let reportColumnDetailList = ctx.isEmpty(userReportInfo.report_column_detail_ids) ? [] : await ctx.classModel.V5.CourseV5ReportColumnDetail.findAll({ where: { id: { $in: eval(userReportInfo.report_column_detail_ids) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'report_column_id', 'sub_title', 'level', 'content', 'advice' ], raw: true });
    reportColumnDetailList = _.concat(reportColumnDetailList, ageReportColumnDetailList);
    const reportColumnList = await ctx.classModel.V5.CourseV5ReportColumn.findAll({ where: { id: { $in: _.uniq(R.pluck('report_column_id', reportColumnDetailList)) } }, order: [[ 'sort', 'asc' ]], attributes: [ 'id', 'title' ], raw: true });
    reportColumnDetailList = _.groupBy(reportColumnDetailList, 'report_column_id');

    const report = [];
    for (const v of reportColumnList) {
      report.push({
        id: v.id,
        title: v.title,
        value: ctx.isEmpty(reportColumnDetailList[v.id]) ? [] : reportColumnDetailList[v.id],
      });
    }

    const tags = await this.getReportTags(userReportInfo);
    const recommendClassList = await this.getRecommendClassListByReport(userReportInfo.answer, userReportInfo.user_uuid, userReportInfo.cat_id);

    const userQuestionnaire = await ctx.classModel.V5.CourseV5Questionnaire.findOne({ where: { user_uuid: userReportInfo.user_uuid, cat_id: userReportInfo.cat_id } });

    const ret = {
      id: reportId,
      category: ctx.isEmpty(category) ? {} : category,
      has_questionnaire: ctx.isEmpty(userQuestionnaire) ? 0 : 1,
      tags,
      report,
      user: userBabyInfo,
      recommend_class_list: recommendClassList,
    };

    return ret;
  }

  // 获取报告列表
  async getReportList() {
    const { ctx } = this;
    const userUuid = ctx.userUuid;

    const userReportList = await ctx.classModel.V5.CourseUserReport.findAll({ where: { user_uuid: userUuid, status: 1, is_deleted: 0 }, order: [[ 'id', 'desc' ]] });
    const categoryIds = _.uniq(R.pluck('cat_id', userReportList));

    let categoryList = await ctx.classModel.V5.CourseV5Category.findAll({ where: { id: { $in: categoryIds } } });
    categoryList = _.groupBy(categoryList, 'id');

    const results = [];
    const checkIds = [];
    for (const v of userReportList) {
      if (!checkIds.includes(v.cat_id)) {
        const category = ctx.isEmpty(categoryList[v.cat_id]) ? '' : categoryList[v.cat_id][0].name;
        results.push({
          id: v.id,
          title: category,
          icon: ctx.isEmpty(categoryList[v.cat_id]) ? '' : categoryList[v.cat_id][0].report_icon,
          created_time: v.created_time,
        });
        checkIds.push(v.cat_id);
      }
    }

    const ret = {
      list: results,
      total_count: results.length,
    };

    return ret;
  }

  // 获取标签
  async getReportTags(report) {
    const { ctx } = this;
    const userBabyInfo = await ctx.classModel.V5.CourseV5UserBaby.findOne({ where: { user_uuid: report.user_uuid, status: 1, is_deleted: 0 } });

    const tags = [];
    if (userBabyInfo.baby_sex === 1) {
      tags.push('小王子');
    } else {
      tags.push('小公主');
    }
    if (!ctx.isEmpty(userBabyInfo.baby_age)) {
      const age = await ctx.classModel.V5.CourseV5Age.findOne({ where: { id: userBabyInfo.baby_age }, attributes: [ 'name' ] });
      if (!ctx.isEmpty(age)) {
        tags.push(age.name);
      }
    }
    if (!ctx.isEmpty(userBabyInfo.baby_birth)) {
      let diffYear = moment().diff(userBabyInfo.baby_birth, 'years');
      diffYear = diffYear > 0 ? diffYear : 1;
      tags.push(`${diffYear}岁`);
    }

    // 问题对应的tag
    const data = eval(report.answer);
    let answerIds = [];
    for (const v of data) {
      answerIds = _.concat(answerIds, v.answers);
    }
    const tagList = await ctx.classModel.V5.CourseV5Answer.findAll({ where: { id: { $in: answerIds } }, attributes: [ 'tag' ] });
    for (const v of tagList) {
      if (!ctx.isEmpty(v.tag)) {
        tags.push(v.tag);
      }
    }

    return tags;
  }

  // 获取推荐课程
  async getRecommendClassListByReport(data, userId, catId) {
    const { ctx } = this;
    // const data = eval(input.data);
    data = eval(data);

    // 取出所有回答
    let answerIds = [];
    for (const v of data) {
      answerIds = _.union(answerIds, v.answers);
    }

    // 获取所有回答筛选相关信息
    let answerFilterList = await ctx.classModel.V5.CourseV5AnswerToFilter.findAll({ where: { answer_id: { $in: answerIds }, status: 1, is_deleted: 0 }, raw: true });
    // 获取年龄对应筛选信息
    const userBabyInfo = await ctx.classModel.V5.CourseV5UserBaby.findOne({ where: { user_uuid: userId, status: 1, is_deleted: 0 } });
    const babyAge = ctx.isEmpty(userBabyInfo) ? 0 : userBabyInfo.baby_age;
    const ageFilterList = await ctx.classModel.V5.CourseV5AgeToFilter.findAll({ where: { age_id: babyAge, cat_id: catId, status: 1, is_deleted: 0 }, raw: true });
    answerFilterList = _.concat(answerFilterList, ageFilterList);

    // 获取所有可以删除的条件数
    let notRetain = 0;
    for (const v of answerFilterList) {
      if (v.is_retain === 0) {
        notRetain++;
      }
    }

    // 循环删除条件，直到满足3个
    let classList = [];
    for (let i = 0; i <= notRetain; i++) {
      const tmpAnswerFilterList = [];
      let tmpCount = 0;
      for (const v of answerFilterList) {
        if (v.is_retain === 0 && tmpCount < i) {
          tmpCount++;
        } else {
          tmpAnswerFilterList.push(v);
        }
      }

      // 筛选
      const where = await this.classFilter(tmpAnswerFilterList, catId, babyAge);
      classList = await ctx.classModel.V5.CourseV5Class.findAll({ where, attributes: [ 'id', 'institution_id', 'name', 'logo', 'age', 'price', 'filter_price', 'price_type', 'mode', 'time', 'class_amount', 'multi_classes', 'cycle', 'sort' ], raw: true });
      if (classList.length >= 3) {
        break;
      }
    }

    // 格式化课程
    classList = await this.formatClassList(classList);

    // 然后进行打分
    classList = await this.calcClassScore(classList, answerFilterList);

    // 按照分数降序，价格升序的顺序排列
    classList = _.orderBy(classList, [ 'score', 'filter_price' ], [ 'desc', 'asc' ]);
    classList = ctx.isEmpty(classList) ? [] : classList.slice(0, 3);

    for (let i = 0; i < classList.length; i++) {
      classList[i].match = 99 - i * 3 - Math.floor(Math.random() * 3);
    }

    return classList;
  }


  // 筛选课程
  async classFilter(answerFilterList, catId, babyAge) {
    const { ctx } = this;

    const where = { status: 1, is_deleted: 0 };
    let classIds = [];
    let classFlag = false;
    let tmpFilter = {};
    let tmpClassList = [];
    for (const v of answerFilterList) {
      if (v.type === 1) {
        // 判断是否是课程的额外字段
        if (v.column_type === 1) { // 课程字段
          switch (v.column) {
            case 'filter_price':
              where.filter_price = ctx.isEmpty(where.filter_price) ? await this.getOptionValue(v) : Object.assign({}, where.filter_price, await this.getOptionValue(v));
              break;
            case 'price_type':
              where.price_type = ctx.isEmpty(where.price_type) ? await this.getOptionValue(v) : Object.assign({}, where.price_type, await this.getOptionValue(v));
              break;
            case 'mode':
              where.mode = ctx.isEmpty(where.mode) ? await this.getOptionValue(v) : Object.assign({}, where.mode, await this.getOptionValue(v));
              break;
            case 'time':
              where.time = ctx.isEmpty(where.time) ? await this.getOptionValue(v) : Object.assign({}, where.time, await this.getOptionValue(v));
              break;
            case 'class_amount':
              where.class_amount = ctx.isEmpty(where.class_amount) ? await this.getOptionValue(v) : Object.assign({}, where.class_amount, await this.getOptionValue(v));
              break;
            case 'multi_classes':
              where.multi_classes = ctx.isEmpty(where.multi_classes) ? await this.getOptionValue(v) : Object.assign({}, where.multi_classes, await this.getOptionValue(v));
              break;
            case 'cycle':
              where.cycle = ctx.isEmpty(where.cycle) ? await this.getOptionValue(v) : Object.assign({}, where.cycle, await this.getOptionValue(v));
              break;
            case 'type':
              tmpFilter = { where: { type_id: await this.getOptionValue(v), status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] };
              tmpClassList = await ctx.classModel.V5.CourseV5ClassToType.findAll(tmpFilter);
              classIds = classFlag ? _.intersection(classIds, R.pluck('class_id', tmpClassList)) : R.pluck('class_id', tmpClassList);
              classFlag = true;
              break;
            case 'frequency':
              tmpFilter = { where: { frequency_id: await this.getOptionValue(v), status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] };
              tmpClassList = await ctx.classModel.V5.CourseV5ClassToFrequency.findAll(tmpFilter);
              classIds = classFlag ? _.intersection(classIds, R.pluck('class_id', tmpClassList)) : R.pluck('class_id', tmpClassList);
              classFlag = true;
              break;
            default:
              break;
          }
        } else if (v.column_type === 2) { // 额外字段
          tmpFilter = { where: { column_id: v.column, value: await this.getOptionValue(v) }, attributes: [ 'class_id' ] };
          tmpClassList = await ctx.classModel.V5.CourseV5ClassToColumn.findAll(tmpFilter);
          classIds = classFlag ? _.intersection(classIds, R.pluck('class_id', tmpClassList)) : R.pluck('class_id', tmpClassList);
          classFlag = true;
        }
      }
    }
    // 分类筛选
    let category = await ctx.classModel.V5.CourseV5Category.findOne({ where: { id: catId } });
    category = ctx.isEmpty(category) ? 0 : category.bind;
    tmpClassList = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { cat_id: category, status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] });

    classIds = classFlag ? _.intersection(classIds, R.pluck('class_id', tmpClassList)) : R.pluck('class_id', tmpClassList);
    // 年级筛选
    tmpClassList = await ctx.classModel.V5.CourseV5ClassToAge.findAll({ where: { age_id: babyAge, status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] });
    classIds = _.intersection(classIds, R.pluck('class_id', tmpClassList));
    where.id = { $in: classIds };

    return where;
  }

  // 获取筛选项操作符和值处理后的数据
  async getOptionValue(filter) {
    let ret = {};
    // 1：=；2：>；3：>=；4：<；5：<=；6：in；7：!=
    switch (filter.column_option) {
      case 1:
        ret = filter.column_value;
        break;
      case 2:
        ret = { $gt: filter.column_value };
        break;
      case 3:
        ret = { $gte: filter.column_value };
        break;
      case 4:
        ret = { $lt: filter.column_value };
        break;
      case 5:
        ret = { $lte: filter.column_value };
        break;
      case 6:
        ret = { $in: eval(filter.column_value) };
        break;
      case 7:
        ret = { $not: filter.column_value };
        break;
      default:
        break;
    }

    return ret;
  }

  // 格式化课程列表
  async formatClassList(classList) {
    const { ctx } = this;

    const classIds = R.pluck('id', classList);

    // 获取所有年龄段
    let classToAge = await ctx.classModel.V5.CourseV5ClassToAge.findAll({ where: { class_id: { $in: classIds }, status: 1, is_deleted: 0 }, attributes: [ 'class_id', 'age_id' ] });
    let ageList = await ctx.classModel.V5.CourseV5Age.findAll({ where: { id: { $in: _.uniq(R.pluck('age_id', classToAge)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ] });
    classToAge = _.groupBy(classToAge, 'class_id');
    ageList = _.groupBy(ageList, 'id');

    // 获取所有课程类型
    let classToType = await ctx.classModel.V5.CourseV5ClassToType.findAll({ where: { class_id: { $in: classIds }, status: 1, is_deleted: 0 }, attributes: [ 'class_id', 'type_id' ] });
    let typeList = await ctx.classModel.V5.CourseV5Type.findAll({ where: { id: { $in: _.uniq(R.pluck('type_id', classToType)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ] });
    classToType = _.groupBy(classToType, 'class_id');
    typeList = _.groupBy(typeList, 'id');

    // 获取所有授课频次
    let classToFrequency = await ctx.classModel.V5.CourseV5ClassToFrequency.findAll({ where: { class_id: { $in: classIds }, status: 1, is_deleted: 0 }, attributes: [ 'class_id', 'frequency_id' ] });
    let frequencyList = await ctx.classModel.V5.CourseV5Frequency.findAll({ where: { id: { $in: _.uniq(R.pluck('frequency_id', classToFrequency)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ] });
    classToFrequency = _.groupBy(classToFrequency, 'class_id');
    frequencyList = _.groupBy(frequencyList, 'id');

    // 获取所有额外字段
    let classToColumn = await ctx.classModel.V5.CourseV5ClassToColumn.findAll({ where: { class_id: { $in: classIds }, status: 1, is_deleted: 0 }, attributes: [ 'class_id', 'column_id', 'value' ] });
    let columnList = await ctx.classModel.V5.CourseV5Column.findAll({ where: { id: { $in: _.uniq(R.pluck('column_id', classToColumn)) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ] });
    classToColumn = _.groupBy(classToColumn, 'class_id');
    columnList = _.groupBy(columnList, 'id');

    // 获取所有机构
    let institutionList = await ctx.classModel.V5.CourseV5Institution.findAll({ where: { id: { $in: _.uniq(R.pluck('institution_id', classList)) } } });
    institutionList = _.groupBy(institutionList, 'id');

    const ret = [];
    for (const v of classList) {
      const classAgeList = [];
      if (!ctx.isEmpty(classToAge[v.id])) {
        for (const j of classToAge[v.id]) {
          if (!ctx.isEmpty(ageList[j.age_id])) {
            classAgeList.push({
              id: j.age_id,
              name: ageList[j.age_id][0].name,
            });
          }
        }
      }

      const classTypeList = [];
      if (!ctx.isEmpty(classToType[v.id])) {
        for (const j of classToType[v.id]) {
          if (!ctx.isEmpty(typeList[j.type_id])) {
            classTypeList.push({
              id: j.type_id,
              name: typeList[j.type_id][0].name,
            });
          }
        }
      }

      const classFrequencyList = [];
      if (!ctx.isEmpty(classToFrequency[v.id])) {
        for (const j of classToFrequency[v.id]) {
          if (!ctx.isEmpty(frequencyList[j.frequency_id])) {
            classFrequencyList.push({
              id: j.frequency_id,
              name: frequencyList[j.frequency_id][0].name,
            });
          }
        }
      }

      const classColumnList = [];
      if (!ctx.isEmpty(classToColumn[v.id])) {
        for (const j of classToColumn[v.id]) {
          if (!ctx.isEmpty(columnList[j.column_id])) {
            classColumnList.push({
              id: j.column_id,
              name: columnList[j.column_id][0].name,
              value: j.value,
              filter_key: `${j.column_id}---${j.value}`,
            });
          }
        }
      }

      const tmpClass = v;
      tmpClass.price_type = await this.service.course.v5.institution.getClassPriceType(tmpClass.price_type);
      tmpClass.mode = await this.service.course.v5.institution.getClassMode(tmpClass.mode);
      tmpClass.institution_name = ctx.isEmpty(institutionList[v.institution_id]) ? '' : institutionList[v.institution_id][0].name;
      tmpClass.institution_logo = ctx.isEmpty(institutionList[v.institution_id]) ? '' : institutionList[v.institution_id][0].logo;
      tmpClass.age_list = classAgeList;
      tmpClass.type_list = classTypeList;
      tmpClass.frequency_list = classFrequencyList;
      tmpClass.column_list = classColumnList;
      tmpClass.score = 0;

      ret.push(tmpClass);
    }

    return ret;
  }

  // 计算所有公司评分
  async calcClassScore(classList, answerFilterList) {
    // 先获取所有评分筛选
    const scoreFilterList = [];
    for (const v of answerFilterList) {
      if (v.type === 2) {
        scoreFilterList.push(v);
      }
    }

    const ret = [];
    for (const v of classList) {
      const tmpClass = v;
      tmpClass.score = await this.calcScore(v, scoreFilterList);
      ret.push(tmpClass);
    }

    return ret;
  }


  // 计算公司分值
  async calcScore(classInfo, scoreFilterList) {
    let score = 0;
    for (const v of scoreFilterList) {
      if (v.type === 2) {
        if (v.column_type === 1) {
          switch (v.column) {
            case 'filter_price':
              score += await this.checkScore(classInfo.filter_price, v.column_option, v.column_value, v.column_score);
              break;
            case 'price_type':
              score += await this.checkScore(classInfo.price_type, v.column_option, v.column_value, v.column_score);
              break;
            case 'mode':
              score += await this.checkScore(classInfo.mode, v.column_option, v.column_value, v.column_score);
              break;
            case 'time':
              score += await this.checkScore(classInfo.time, v.column_option, v.column_value, v.column_score);
              break;
            case 'class_amount':
              score += await this.checkScore(classInfo.class_amount, v.column_option, v.column_value, v.column_score);
              break;
            case 'multi_classes':
              score += await this.checkScore(classInfo.multi_classes, v.column_option, v.column_value, v.column_score);
              break;
            case 'cycle':
              score += await this.checkScore(classInfo.cycle, v.column_option, v.column_value, v.column_score);
              break;
            case 'type':
              for (const j of classInfo.type_list) {
                score += await this.checkScore(String(j.id), v.column_option, v.column_value, v.column_score);
              }
              break;
            case 'frequency':
              for (const j of classInfo.frequency_list) {
                score += await this.checkScore(String(j.id), v.column_option, v.column_value, v.column_score);
              }
              break;
            case 'age':
              for (const j of classInfo.age_list) {
                score += await this.checkScore(String(j.id), v.column_option, v.column_value, v.column_score);
              }
              break;
            default:
              break;
          }
        } else {
          for (const j of classInfo.column_list) {
            if (v.column === j.id) {
              score += await this.checkScore(j.value, v.column_option, v.column_value, v.column_score);
            }
          }
        }
      }
    }

    return score;
  }

  // 判断是否符合条件
  async checkScore(value, option, filter, score) {
    let ret = 0;

    switch (option) {
      case 1:
        ret = value === filter ? Number(score) : 0;
        break;
      case 2:
        ret = value > filter ? Number(score) : 0;
        break;
      case 3:
        ret = value >= filter ? Number(score) : 0;
        break;
      case 4:
        ret = value < filter ? Number(score) : 0;
        break;
      case 5:
        ret = value <= filter ? Number(score) : 0;
        break;
      case 6:
        filter = eval(filter);
        score = eval(score);
        for (const i in filter) {
          if (filter[i] === value && score.length > i) {
            ret += Number(score[i]);
          }
        }
        break;
      case 7:
        ret = value !== filter ? Number(score) : 0;
        break;
      default:
        break;
    }

    return ret;
  }


  // 获取所有报告推荐课程
  async getAllReportRecommendClassList() {
    const { ctx } = this;

    const userReportList = await ctx.classModel.V5.CourseUserReport.findAll({ where: { user_uuid: ctx.userUuid, status: 1, is_deleted: 0 }, raw: true });
    const categoryIds = _.uniq(R.pluck('cat_id', userReportList));

    let categoryList = await ctx.classModel.V5.CourseV5Category.findAll({ where: { id: { $in: categoryIds } }, attributes: [ 'id', 'name', 'url', 'color' ] });
    categoryList = _.groupBy(categoryList, 'id');

    const results = [];
    const checkIds = [];
    for (const v of userReportList) {
      if (!checkIds.includes(v.cat_id)) {
        results.push({
          id: v.id,
          category: ctx.isEmpty(categoryList[v.cat_id]) ? {} : categoryList[v.cat_id][0],
          answer: v.answer,
        });
        checkIds.push(v.cat_id);
      }
    }

    const handle = [];
    for (const i in results) {
      handle.push(this.getRecommendClassListByReport(results[i].answer, ctx.userUuid, results[i].category.id));
    }
    const handleResult = await Promise.all(handle).then(result => {
      return result;
    }).catch(error => {
      ctx.failed(error);
    });

    const ret = [];
    for (const i in results) {
      ret.push({
        id: results[i].id,
        category: results[i].category,
        recommend_class_list: handleResult[i],
      });
    }

    return { list: ret };
  }
}

module.exports = ReportService;
