
'use strict';

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

class InstitutionSubService extends Service {
  // 课程列表
  async getClassList(input) {
    const { ctx } = this;
    const page = Number(input.page) || 1;
    const page_size = Number(input.page_size) || 10;
    const offset = (page - 1) * page_size;
    const attributes = [ 'id', 'institution_id', 'name', 'logo', 'age', 'price', 'price_type', 'mode', 'time', 'class_amount', 'multi_classes', 'cycle', 'description', 'sort' ];
    const filter = { where: { status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], limit: page_size, offset, attributes, raw: true };
    let filterIds = [];
    let flag = false;
    // 年龄筛选
    if (!ctx.isEmpty(input.age)) {
      const filterByAge = await ctx.classModel.V5.CourseV5ClassToAge.findAll({ where: { age_id: input.age, status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] });
      filterIds = R.pluck('class_id', filterByAge);
      flag = true;
    }
    // 科目类型
    if (!ctx.isEmpty(input.category)) {
      const filterByCategory = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { cat_id: input.category, status: 1, is_deleted: 0 }, attributes: [ 'class_id' ] });
      filterIds = flag ? _.intersection(filterIds, R.pluck('class_id', filterByCategory)) : R.pluck('class_id', filterByCategory);
      flag = true;
    }
    // 课程状态
    if (!ctx.isEmpty(input.mode)) {
      filter.where.mode = input.mode;
    }
    // 课程类型
    if (!ctx.isEmpty(input.price_type)) {
      filter.where.price_type = input.price_type;
    }
    if (flag) {
      filter.where.id = { $in: filterIds };
    }

    const classList = await ctx.classModel.V5.CourseV5Class.findAndCountAll(filter);
    if (classList.count === 0) {
      return { list: [], total_count: 0, page, page_size };
    }

    // 用户收藏的课程
    let collectedIds = [];
    if (!ctx.isEmpty(ctx.userUuid)) {
      const userCollection = await ctx.classModel.V5.CourseUserCollection.findAll({ where: { user_uuid: ctx.userUuid, is_deleted: 0, type: 3 }, raw: true });
      collectedIds = R.pluck('type_id', userCollection);
    }
    for (const i in classList.rows) {
      classList.rows[i].is_collected = collectedIds.includes(classList.rows[i].id) ? 1 : 0;
    }

    // 获取课程类型
    let classToCategory = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { class_id: { $in: R.pluck('id', classList.rows) } }, attributes: [ 'cat_id', 'class_id' ] });
    let categoryList = await ctx.classModel.V5.CourseV5Category.findAll({ where: { id: { $in: R.pluck('cat_id', classToCategory) } }, attributes: [ 'id', 'name' ] });
    classToCategory = _.groupBy(classToCategory, 'class_id');
    categoryList = _.groupBy(categoryList, 'id');

    // 获取机构
    let institutionList = await ctx.classModel.V5.CourseV5Institution.findAll({ where: { id: { $in: R.pluck('institution_id', classList.rows) } }, attributes: [ 'id', 'name', 'logo' ] });
    institutionList = _.groupBy(institutionList, 'id');

    for (const i in classList.rows) {
      const classCategoryList = [];
      if (!ctx.isEmpty(classToCategory[classList.rows[i].id])) {
        for (const j of classToCategory[classList.rows[i].id]) {
          if (!ctx.isEmpty(categoryList[j.cat_id])) {
            classCategoryList.push({
              id: j.cat_id,
              name: categoryList[j.cat_id][0].name,
            });
          }
        }
      }
      classList.rows[i].price_type = await this.getClassPriceType(classList.rows[i].price_type);
      classList.rows[i].mode = await this.getClassMode(classList.rows[i].mode);
      classList.rows[i].category = classCategoryList;
      classList.rows[i].institution_name = ctx.isEmpty(institutionList[classList.rows[i].institution_id]) ? '' : institutionList[classList.rows[i].institution_id][0].name;
      classList.rows[i].institution_logo = ctx.isEmpty(institutionList[classList.rows[i].institution_id]) ? '' : institutionList[classList.rows[i].institution_id][0].logo;
    }

    const ret = {
      list: classList.rows,
      total_count: classList.count,
      page,
      page_size,
    };
    return ret;
  }


  // 课程详情
  async getClassInfo(id) {
    const { ctx } = this;
    const attributes = [ 'id', 'institution_id', 'name', 'logo', 'age', 'price', 'price_type', 'mode', 'time', 'class_amount', 'multi_classes', 'cycle', 'description', 'button_style', 'button_text', 'button_type', 'button_sub_text', 'button_url', 'button_pay_text', 'top_price', 'pay_price', 'sub_title', 'pay_count', 'sort' ];
    const classInfo = await ctx.classModel.V5.CourseV5Class.findOne({ where: { id, status: 1, is_deleted: 0 }, attributes, raw: true });
    if (ctx.isEmpty(classInfo)) {
      ctx.failed('数据不存在');
    }


    const isCollected = ctx.isEmpty(ctx.userUuid) ? '' : await ctx.classModel.V5.CourseUserCollection.findOne({ where: { user_uuid: ctx.userUuid, type: 3, type_id: id, is_deleted: 0 } });
    classInfo.is_collected = ctx.isEmpty(isCollected) ? 0 : 1;

    // 额外字段
    const classColumns = await ctx.classModel.V5.CourseV5ClassToColumn.findAll({ where: { class_id: id, status: 1, is_deleted: 0 } });
    let columnList = await ctx.classModel.V5.CourseV5Column.findAll({ where: { id: { $in: R.pluck('column_id', classColumns) }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ], raw: true });
    columnList = _.groupBy(columnList, 'id');
    for (const i in columnList) {
      columnList[i][0].value = [];
    }

    // 机构数据
    const institution = await ctx.classModel.V5.CourseV5Institution.findOne({ where: { id: classInfo.institution_id } });

    // 学员成果
    const studentWorks = await ctx.classModel.V5.CourseV5StudentWorks.findAll({ where: { class_id: id, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ]], attributes: [ 'id', 'name', 'sub_title', 'description', 'video_url', 'cover_image' ] });

    // 顶部图片
    const imageList = await ctx.classModel.V5.CourseImages.findAll({ where: { type: 5, type_id: id, status: 'online', is_deleted: 0 }, order: [[ 'sort', 'asc' ]] });
    const images = [];
    for (const v of imageList) {
      images.push({
        id: v.id,
        url: v.is_video > 0 ? v.video_url : v.image_url,
        is_video: v.is_video,
      });
    }

    // 课程分类
    const categoryList = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { class_id: id, status: 1, is_deleted: 0 }, attributes: [ 'cat_id' ] });
    const category = await ctx.classModel.V5.CourseV5Category.findAll({ where: { id: { $in: R.pluck('cat_id', categoryList) } }, attributes: [ 'id', 'name' ] });


    // 班型
    const typeList = await ctx.classModel.V5.CourseV5ClassToType.findAll({ where: { class_id: id, status: 1, is_deleted: 0 }, attributes: [ 'type_id' ] });
    const type = await ctx.classModel.V5.CourseV5Type.findAll({ where: { id: { $in: R.pluck('type_id', typeList) } }, attributes: [ 'id', 'name' ] });

    // 授课频次
    const frequencyList = await ctx.classModel.V5.CourseV5ClassToFrequency.findAll({ where: { class_id: id, status: 1, is_deleted: 0 }, attributes: [ 'frequency_id' ] });
    const frequency = await ctx.classModel.V5.CourseV5Frequency.findAll({ where: { id: { $in: R.pluck('frequency_id', frequencyList) } }, attributes: [ 'id', 'name' ] });

    // 关联课程
    const relationList = await ctx.classModel.V5.CourseV5ClassRelation.findAll({ where: { class_id: id, status: 1, is_deleted: 0 }, attributes: [ 'relation_id' ] });
    const relation = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: R.pluck('relation_id', relationList) } }, attributes: [ 'id', 'name', 'price', 'mode', 'logo' ], raw: true });
    for (const i in relation) {
      relation[i].mode = await this.getClassMode(relation[i].mode);
    }

    const columns = [];
    for (const v of classColumns) {
      if (!ctx.isEmpty(columnList[v.column_id])) {
        columnList[v.column_id][0].value.push({
          id: v.id,
          value: v.value,
        });
      }
    }
    for (const i in columnList) {
      if (columnList[i][0].value.length > 0) {
        columns.push(columnList[i][0]);
      }
    }
    classInfo.columns = columns;

    // 是否已购买
    const userOrder = ctx.isEmpty(ctx.userUuid) ? {} : await ctx.classModel.V5.CourseUserOrder.findOne({ where: { user_uuid: ctx.userUuid, class_id: id, status: 1, is_deleted: 0 }, attributes: [ 'id' ] });
    classInfo.is_bought = ctx.isEmpty(userOrder) ? 0 : 1;

    // 视频总数
    const videoCount = await ctx.classModel.V5.CourseV5Video.count({ where: { class_id: id, status: 1, is_deleted: 0 } });

    // 订单总数
    const orderCount = await ctx.classModel.V5.CourseUserOrder.count({ where: { class_id: id, status: 1, is_deleted: 0 } });

    classInfo.price_type = await this.getClassPriceType(classInfo.price_type);
    classInfo.mode = await this.getClassMode(classInfo.mode);
    classInfo.student_works = studentWorks;
    classInfo.images = images;
    classInfo.category = category;
    classInfo.type = type;
    classInfo.institution_name = ctx.isEmpty(institution) ? '' : institution.name;
    classInfo.institution_logo = ctx.isEmpty(institution) ? '' : institution.logo;
    classInfo.institution_description = ctx.isEmpty(institution) ? '' : institution.description;
    classInfo.institution_title = ctx.isEmpty(institution) ? '' : institution.title;
    classInfo.pay_count += orderCount;
    classInfo.video_count = videoCount;
    classInfo.frequency = frequency;
    classInfo.relation = relation;

    return classInfo;
  }

  // 用户收藏课程列表
  async getCollectionClassList(input) {
    const { ctx } = this;
    const page = Number(input.page) || 1;
    const page_size = Number(input.page_size) || 10;
    const offset = (page - 1) * page_size;
    const attributes = [ 'id', 'institution_id', 'name', 'logo', 'age', 'price', 'price_type', 'mode', 'time', 'class_amount', 'multi_classes', 'cycle', 'description', 'sort' ];

    // 用户收藏的课程
    const userCollection = await ctx.classModel.V5.CourseUserCollection.findAndCountAll({ where: { user_uuid: ctx.userUuid, is_deleted: 0, type: 3 }, raw: true });
    const collectedIds = R.pluck('type_id', userCollection.rows);
    const filter = { where: { id: { $in: collectedIds }, status: 1, is_deleted: 0 }, limit: page_size, offset, attributes, raw: true };
    const classList = await ctx.classModel.V5.CourseV5Class.findAll(filter);
    for (const i in classList) {
      classList[i].price_type = await this.getClassPriceType(classList[i].price_type);
      classList[i].mode = await this.getClassMode(classList[i].mode);
    }

    const ret = {
      list: classList,
      total_count: userCollection.count,
      page,
      page_size,
    };
    return ret;
  }

  // 收藏课程
  async collectClass(id) {
    const { ctx } = this;
    // 先检查课程是否存在
    const classInfo = await ctx.classModel.V5.CourseV5Class.findOne({ where: { id, is_deleted: 0 }, attributes: [ 'id' ] });
    if (ctx.isEmpty(classInfo)) {
      ctx.failed('课程不存在');
    }

    // 检查是否已收藏
    const collectInfo = await ctx.classModel.V5.CourseUserCollection.findOne({ where: { user_uuid: ctx.userUuid, type: 3, type_id: id, is_deleted: 0 } });
    if (!ctx.isEmpty(collectInfo)) {
      ctx.failed('请勿重复收藏');
    }

    const data = {
      user_uuid: ctx.userUuid,
      institution_id: 0,
      type: 3,
      type_id: id,
      is_deleted: 0,
      created_time: moment().format('YYYY-MM-DD hh:mm:ss'),
    };
    await ctx.classModel.V5.CourseUserCollection.create(data);

    const ret = { result: true };
    return ret;
  }

  // 取消收藏
  async delCollectClass(class_id) {
    const { ctx } = this;
    let ret = await ctx.classModel.V5.CourseUserCollection.findOne({ where: { user_uuid: ctx.userUuid, is_deleted: 0, type: 3, type_id: class_id } });
    if (ctx.isEmpty(ret)) {
      ctx.failed('尚未收藏');
    }

    ret = await ctx.classModel.V5.CourseUserCollection.update({ is_deleted: 1 }, { where: { id: ret.id } });

    return { result: true };
  }

  // 获取科普文章
  async getArticleByCategory(catId) {
    const { ctx } = this;

    const article = await ctx.classModel.V5.CourseV5Article.findOne({ where: { cat_id: catId, status: 1, is_deleted: 0 } });
    if (ctx.isEmpty(article)) {
      return {};
    }

    // 问答
    const qa = await ctx.classModel.V5.CourseV5ArticleQA.findAll({ where: { article_id: article.id, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ]], attributes: [ 'id', 'question', 'answer' ] });

    const ret = {
      id: article.id,
      cat_id: article.cat_id,
      image: article.image,
      content: article.content,
      qa,
    };

    return ret;
  }


  // 课程类型映射
  async getClassPriceType(key) {
    const list = [ '免费公益课', '低价体验课', '正价课' ];

    const ret = (key > 0 && key <= list.length) ? list[key - 1] : '';
    return ret;
  }

  // 课程状态映射
  async getClassMode(key) {
    const list = [ '直播', '录播(动画)', '录播(真人)', 'APP', '小程序' ];

    const ret = (key > 0 && key <= list.length) ? list[key - 1] : '';
    return ret;
  }

  // 获取牛通社首页
  async getNiutongshe() {
    const ret = {
      banner: '',
      list: [
        {
          class_id: 1,
          image: '',
          title: '动力拼音',
          sub_title: '轻松掌握声母韵母拼读108 个高频音节',
        }, {
          class_id: 2,
          image: '',
          title: '闪卡识字',
          sub_title: '联想图像情景学习法入学即能识千字',
        }, {
          class_id: 3,
          image: '',
          title: '魔数思维',
          sub_title: '3大模块100道题培养抽象 逻辑思维力',
        }, {
          class_id: 4,
          image: '',
          title: '家长课堂',
          sub_title: '协助父母一站式解决孩子早期教育问题',
        },
      ],
    };

    return ret;
  }


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

    // 获取课程类型
    let classToCategory = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { class_id: { $in: _.uniq(R.pluck('id', classList)) } }, attributes: [ 'cat_id', 'class_id' ] });
    let categoryList = await ctx.classModel.V5.CourseV5Category.findAll({ where: { id: { $in: _.uniq(R.pluck('cat_id', classToCategory)) } }, attributes: [ 'id', 'name' ] });
    classToCategory = _.groupBy(classToCategory, 'class_id');
    categoryList = _.groupBy(categoryList, 'id');

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

    for (const i in classList) {
      const classCategoryList = [];
      if (!ctx.isEmpty(classToCategory[classList[i].id])) {
        for (const j of classToCategory[classList[i].id]) {
          if (!ctx.isEmpty(categoryList[j.cat_id])) {
            classCategoryList.push({
              id: j.cat_id,
              name: categoryList[j.cat_id][0].name,
            });
          }
        }
      }
      classList[i].price_type = await this.getClassPriceType(classList[i].price_type);
      classList[i].mode = await this.getClassMode(classList[i].mode);
      classList[i].category = classCategoryList;
      classList[i].institution_name = ctx.isEmpty(institutionList[classList[i].institution_id]) ? '' : institutionList[classList[i].institution_id][0].name;
      classList[i].institution_logo = ctx.isEmpty(institutionList[classList[i].institution_id]) ? '' : institutionList[classList[i].institution_id][0].logo;
    }

    return classList;
  }


  async getSearchRecommend(input) {
    const { ctx } = this;
    const word = input.word || '';
    const limit = 10;
    const offset = 0;

    const classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { name: { $like: `%${word}%` }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ], raw: true, limit, offset });
    const ret = { list: classList };
    return ret;
  }

  // 获取搜索结果
  async getSearch(input) {
    const { ctx } = this;
    const word = input.word || '';

    // 先查询机构名称的
    const institutionList = await ctx.classModel.V5.CourseV5Institution.findAll({ where: { name: { $like: `%${word}%` }, status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ], raw: true });
    const institutionIds = R.pluck('id', institutionList);

    let classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { $or: [{ name: { $like: `%${word}%` } }, { institution_id: { $in: institutionIds } }], status: 1, is_deleted: 0 }, attributes: [ 'id', 'name' ], raw: true });
    classList = await this.formatClassList(classList);

    const ret = {
      list: classList,
      count: classList.length,
    };

    return ret;
  }

  // 获取视频列表
  async getVideoList(input) {
    const { ctx } = this;
    const classId = input.class_id || 0;
    const userUuid = ctx.userUuid;

    const videoList = await ctx.classModel.V5.CourseV5Video.findAll({ where: { class_id: classId, status: 1, is_deleted: 0 }, attributes: [ 'id', 'class_id', 'title', 'time', 'cover_image', 'is_free' ], order: [[ 'sort', 'asc' ]], raw: true });

    let latestVideoId = 0;
    let valid = 0;
    if (!ctx.isEmpty(userUuid)) {
      const userVideo = await ctx.classModel.V5.CourseV5UserVideo.findOne({ where: { user_uuid: userUuid, class_id: classId } });
      latestVideoId = ctx.isEmpty(userVideo) ? 0 : userVideo.video_id;
      const userOrder = await ctx.classModel.V5.CourseUserOrder.findOne({ where: { user_uuid: userUuid, class_id: classId, status: 1, is_deleted: 0 }, attributes: [ 'id' ] });
      valid = ctx.isEmpty(userOrder) ? 0 : 1;
    }

    for (const i in videoList) {
      videoList[i].is_latest = videoList[i].id === latestVideoId ? 1 : 0;
      videoList[i].valid = videoList[i].is_free === 1 ? 1 : valid;
    }
    const ret = {
      list: videoList,
    };

    return ret;
  }

  // 获取视频详情
  async getVideoInfo(id) {
    const { ctx } = this;
    const userUuid = ctx.userUuid;
    if (ctx.isEmpty(userUuid)) {
      ctx.failed('用户异常');
    }

    const video = await ctx.classModel.V5.CourseV5Video.findOne({ where: { id, status: 1, is_deleted: 0 } });
    if (ctx.isEmpty(video)) {
      ctx.failed('视频不存在');
    }

    // 校验用户是否允许播放
    if (video.is_free === 0) {
      const order = await ctx.classModel.V5.CourseUserOrder.findOne({ where: { class_id: video.class_id, user_uuid: userUuid, status: 1, is_deleted: 0 } });
      if (ctx.isEmpty(order)) {
        ctx.failed('购买后才能学习哦');
      }
    }

    // 更新最新播放
    const userVideo = await ctx.classModel.V5.CourseV5UserVideo.findOne({ where: { user_uuid: userUuid, class_id: video.class_id } });
    if (ctx.isEmpty(userVideo)) {
      await ctx.classModel.V5.CourseV5UserVideo.create({ user_uuid: userUuid, class_id: video.class_id, video_id: video.id });
    } else {
      await ctx.classModel.V5.CourseV5UserVideo.update({ video_id: video.id }, { where: { id: userVideo.id } });
    }

    const ret = {
      id: video.id,
      class_id: video.class_id,
      title: video.title,
      time: video.time,
      cover_image: video.cover_image,
      url: video.url,
      is_free: video.is_free,
      is_latest: 1,
    };

    return ret;
  }


  // 课程首页
  async getHomeClassList(input) {
    const { ctx } = this;
    const cat_id = Number(input.cat_id) || 0;
    const attributes = [ 'id', 'institution_id', 'name', 'logo', 'age', 'price', 'price_type', 'mode', 'time', 'class_amount', 'multi_classes', 'cycle', 'description', 'sort' ];

    const results = [];
    let classList = [];

    const classAll = await ctx.classModel.V5.CourseV5ClassToCat.findAll({ where: { cat_id, status: 1, is_deleted: 0 } });
    const classIds = R.pluck('class_id', classAll);

    // 体验课
    classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 1, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
    classList = await this.formatClassList(classList);
    for (const i in classList) {
      classList[i].institution_icon = '';
    }
    results.push({
      title: '体验课',
      value: 1,
      class: classList,
    });

    // 低价课
    classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 2, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
    classList = await this.formatClassList(classList);
    for (const i in classList) {
      classList[i].institution_icon = '';
    }
    results.push({
      title: '低价课',
      value: 2,
      class: classList,
    });

    // 精品课
    classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 3, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
    classList = await this.formatClassList(classList);
    for (const i in classList) {
      classList[i].institution_icon = '';
    }
    results.push({
      title: '精品课',
      value: 3,
      class: classList,
    });

    const ret = {
      list: results,
    };

    return ret;
  }
}

module.exports = InstitutionSubService;
