import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Like, Not, Repository } from 'typeorm';
import { CreateQuestionDto } from 'src/assessment-evaluation/dto/dtos-question-manager/question/create-question.dto';
import { PagingQuestionDto } from 'src/assessment-evaluation/dto/dtos-question-manager/question/paging-question.dto';
import { UpdateQuestionDto } from 'src/assessment-evaluation/dto/dtos-question-manager/question/update-question.dto';
import { KnowledgePoint } from 'src/assessment-evaluation/entities/entities-question-manager/knowledge-point.entity';
import { QuestionDifficultyLevel } from 'src/assessment-evaluation/entities/entities-question-manager/question-difficulty-level.entity';
import { QuestionType } from 'src/assessment-evaluation/entities/entities-question-manager/question-type.entity';
import { Question } from 'src/assessment-evaluation/entities/entities-question-manager/question.entity';
import { GetQuestionCountDto } from 'src/assessment-evaluation/dto/dtos-question-manager/question/get-question-count.dto';

@Injectable()
export class QuestionService {
  constructor(
    @InjectRepository(Question)
    private QuestionRepository: Repository<Question>,
    @InjectRepository(QuestionType)
    private QuestionTypeRepository: Repository<QuestionType>,
    @InjectRepository(QuestionDifficultyLevel)
    private QuestionDifficultyLevelRepository: Repository<QuestionDifficultyLevel>,
    @InjectRepository(KnowledgePoint)
    private KnowledgePointRepository: Repository<KnowledgePoint>,
  ) {}

  /* 
    导入试题
  */
  async importQuestions(questions: CreateQuestionDto[]) {
    return await this.QuestionRepository.insert(questions);
  }

  /* 导出试题 */
  async exportAllQuestion(classifyId: number) {
    const querys = this.QuestionRepository.createQueryBuilder('q')
      .leftJoin(QuestionType, 'qt', 'qt.id=q.type')
      .leftJoin(QuestionDifficultyLevel, 'qdl', 'qdl.id = q.difficulty_level')
      .leftJoin(KnowledgePoint, 'kp', 'kp.id=q.knowledge_id')
      .select(
        `
        q.title as '题目',
        qt.name as '类型',
        qdl.name as '难易程度',
        kp.name as '知识点',
        q.options as '选项',
        q.answer as '答案',
        q.analysis as '答案解析'
        `,
      )
      .where('q.del_flag=0');
    if (classifyId) {
      querys.andWhere('q.classify_id = ' + classifyId);
    }

    return await querys.getRawMany();
  }

  /* 创建试题 */
  async create(createQuestionDto: CreateQuestionDto) {
    // 是否含有改type类型
    const hasType = await this.QuestionTypeRepository.findOneBy({
      delFlag: 0,
      id: createQuestionDto.type,
    });
    if (!hasType) {
      console.log(hasType);
      throw '[type]字段 - 试题类型不存在';
    }
    const hasDifficultyLevel =
      await this.QuestionDifficultyLevelRepository.findOneBy({
        delFlag: 0,
        id: createQuestionDto.difficultyLevel,
      });
    if (!hasDifficultyLevel) {
      throw '[difficultyLevel]字段 - 难易程度不存在';
    }
    const hasKnowledgePoint = await this.KnowledgePointRepository.findOneBy({
      delFlag: 0,
      id: createQuestionDto.knowledgeId,
    });
    if (!hasKnowledgePoint) {
      // throw '[knowledgeId]字段 - 知识点不存在';
      createQuestionDto.knowledgeId = null;
    }
    await this.QuestionRepository.insert(createQuestionDto);
    return true;
  }
  /* 
    获取一道试题
  */
  async findOne(id: number) {
    return await this.QuestionRepository.findOneBy({ id });
  }
  /* 
  随机抽题
  */
  async random(GetQuestionCountDto: GetQuestionCountDto) {
    let sql = `select u.*,u.type as typeId,
    qt.name as type,
    qt.element as element
    from question u
    inner join (select id from question where del_flag=0`;
    if (GetQuestionCountDto.type) {
      sql += ` AND type=${GetQuestionCountDto.type}`;
    }
    if (GetQuestionCountDto.classifyId) {
      sql += ` AND classify_id=${GetQuestionCountDto.classifyId}`;
    }
    if (GetQuestionCountDto.difficultyLevel) {
      sql += ` AND difficulty_level=${GetQuestionCountDto.difficultyLevel}`;
    }
    if (GetQuestionCountDto.student) {
      sql += ` AND student = ${GetQuestionCountDto.student}`;
    }
    if (GetQuestionCountDto.excludeIds) {
      sql += ` AND id not in (${GetQuestionCountDto.excludeIds.join(',')})`;
    }
    sql += ` order by RAND() limit ${GetQuestionCountDto.count}) as t on t.id=u.id left join question_type qt on qt.id=u.type`;
    return await this.QuestionRepository.query(sql);
  }
  /* 
    查找所有试题
  */
  async findAll() {
    // return this.QuestionRepository.find({
    //   select: ['id', 'type', 'difficultyLevel', 'title', 'options', 'answer', 'analysis', 'knowledgeId'],
    //   where: { delFlag: 0 },
    // });
    return await this.QuestionRepository.createQueryBuilder('questions')
      .where({ delFlag: 0 })
      .leftJoinAndSelect(QuestionType, 'types', 'questions.type = types.id')
      .leftJoinAndSelect(
        QuestionDifficultyLevel,
        'levels',
        'questions.difficultyLevel = levels.id',
      )
      .leftJoinAndSelect(
        KnowledgePoint,
        'knows',
        'questions.knowledgeId = knows.id',
      )
      .select(
        `
    questions.id as id,
    questions.id as questions_id,
    questions.type as typeId,
    types.name as type,
    questions.difficultyLevel as difficultyLevelId,
    levels.name as difficultyLevel,
    questions.knowledgeId as knowledgeId,
    knows.name as knowledgePoint
    `,
      )
      .getRawMany();
  }

  /* 
    分页查找所有试题
  */
  async paging(pagingInfo: PagingQuestionDto) {
    const {
      currentPage,
      pageSize,
      classifyId,
      title,
      type,
      difficultyLevel,
      excludeIds,
      student,
    } = pagingInfo;
    type PagingParamsMap = {
      delFlag: number;
      classifyId: number | null;
      title: any | null;
      type: number | null;
      difficultyLevel: number | null;
      id: any | null;
      student: number | null;
    };

    // eslint-disable-next-line prefer-const
    let whereMap: PagingParamsMap = {
      delFlag: 0,
      classifyId: null,
      title: null,
      type: null,
      difficultyLevel: null,
      id: null,
      student: null,
    };
    console.log(pagingInfo, whereMap);
    try {
      let sql = `select
      questions.id as id,
      questions.type as typeId,
      questions.title as title,
      questions.student as student,
      users.name as creator ,
      questions.creator as creatorId,
      questions.classify_id  as classifyId,
      qc.name  as classify,
      questions.options as options,
      date_format(questions.create_time, '%Y-%m-%d') as createTime,
      questions.answer as answer,
      types.name as type,
      types.element as element,
      questions.difficulty_level as difficultyLevelId,
      levels.name as difficultyLevel,
      questions.knowledge_id as knowledgeId,
      knows.name as knowledgePoint
    from
      question questions
    left join question_type types on
      questions.type = types.id
    left join question_difficulty_level levels on
      questions.difficulty_level = levels.id
    left join knowledge_point knows on
      questions.knowledge_id = knows.id
      left join user users on questions.creator = users.id
      left join question_classify qc on questions.classify_id  = qc.id
    where
    questions.del_flag = 0 `;
      if (classifyId) {
        sql += ` AND questions.classify_id = ${classifyId}`;
        whereMap.classifyId = classifyId;
      }
      if (title) {
        sql += ` AND questions.title LIKE '%${title}%'`;
        whereMap.title = Like(`%${title}%`);
      }
      if (difficultyLevel) {
        sql += ` AND questions.difficulty_level = ${difficultyLevel}`;
        whereMap.difficultyLevel = difficultyLevel;
      }
      if (type) {
        sql += ` AND questions.type = ${type}`;
        whereMap.type = type;
      }
      console.log('excludeIds', excludeIds);
      if (excludeIds) {
        sql += ` AND questions.id not in (${excludeIds.join(',')})`;
        whereMap.id = Not(In(excludeIds));
      }
      if (student) {
        sql += ` AND questions.student = ${student}`;
        whereMap.student = student;
      }
      sql += `
    order by
      questions.id desc limit ?,?`;
      const getPagingQuestions = await this.QuestionRepository.query(sql, [
        +(currentPage - 1) * pageSize,
        +pageSize,
      ]);
      // console.log(sql);
      const total = await this.QuestionRepository.countBy(whereMap);
      return { total, currentPage, pageSize, data: getPagingQuestions };
    } catch (err) {
      throw '分页查询失败，错误详情：' + err;
    }
  }

  /* 
    更新试题
  */
  async updateStudentCanUse(id: number, updateQuestionDto: any) {
    return this.QuestionRepository.update(id, updateQuestionDto);
  }
  /* 
    更新试题
  */
  async update(id: number, updateQuestionDto: UpdateQuestionDto) {
    console.log('<===============>', typeof updateQuestionDto.knowledgeId);
    return this.QuestionRepository.update(id, updateQuestionDto);
  }

  /* 
    删除试题
  */
  async remove(id: number) {
    await this.QuestionRepository.update(id, { delFlag: 1 });
    return true;
  }

  /* 
    根据条件获取试题数
  */
  async getCount(GetQuestionCountDto: GetQuestionCountDto) {
    // return await this.QuestionRepository.countBy({
    //   delFlag: 0,
    //   ...GetQuestionCountDto,
    // });
    let sql = `SELECT COUNT(1) AS cnt FROM question Question WHERE Question.del_flag = 0`;
    if (GetQuestionCountDto.classifyId) {
      sql += ` AND Question.classify_id = ${GetQuestionCountDto.classifyId}`;
    }
    if (GetQuestionCountDto.type) {
      sql += ` AND Question.type = ${GetQuestionCountDto.type}`;
    }
    if (GetQuestionCountDto.difficultyLevel) {
      sql += ` AND Question.difficulty_level = ${GetQuestionCountDto.difficultyLevel}`;
    }
    if (GetQuestionCountDto.student) {
      sql += ` AND Question.student = ${GetQuestionCountDto.student}`;
    }
    if (GetQuestionCountDto.excludeIds) {
      sql += ` AND Question.id not in (${GetQuestionCountDto.excludeIds.join(
        ',',
      )})`;
    }
    const res = await this.QuestionRepository.query(sql);
    return res[0].cnt;
  }

  /* 
    根据ID获取试题详情
  */
  async getQuestions(ids: number[]) {
    return await this.QuestionRepository.query(`
    select * from question where id in (${ids.join(',')})`);
  }
}
