import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateStudentOnlineExamDto } from 'src/assessment-evaluation/dto/dtos-exam-manager/student-online-exam/create-student-online-exam.dto';
import { UpdateStudentOnlineExamDto } from 'src/assessment-evaluation/dto/dtos-exam-manager/student-online-exam/update-student-online-exam.dto';
import { Repository } from 'typeorm';
import { StudentOnlineExam } from 'src/assessment-evaluation/entities/entities-exam-manager/student-online-exam.entity';
import { PagingStudentOnlineExamDto } from 'src/assessment-evaluation/dto/dtos-exam-manager/student-online-exam/paging-student-online-exam.dto';
import { TokenDataEntity } from 'src/common/entities/token-data.entity';

@Injectable()
export class StudentOnlineExamService {
  constructor(
    @InjectRepository(StudentOnlineExam)
    private StudentOnlineExam: Repository<StudentOnlineExam>,
  ) {}
  /* 
    分发考试给一个学生
  */
  async createOne(CreateStudentOnlineExamDto: CreateStudentOnlineExamDto) {
    return await this.StudentOnlineExam.save(CreateStudentOnlineExamDto);
  }
  /* 
    批量分发考试给学生
  */
  async create(CreateStudentOnlineExamDto: CreateStudentOnlineExamDto | any[]) {
    await this.StudentOnlineExam.insert(CreateStudentOnlineExamDto);
    return true;
  }
  /* 
    获取考试最后一次历史记录
  */
  async findLastExam(id) {
    const lastArr = await this.StudentOnlineExam.query(
      `select * from online_exam_history oeh where online_exam_id = ${id} order by oeh.create_time desc limit 1`,
    );
    return lastArr?.length > 0 ? lastArr[0] : null;
  }
  /* 
    查询某个考试历史
  */
  async findOneById(id, checkDel = true) {
    const where: any = {
      id,
    };
    if (checkDel) {
      where.delFlag = 0;
    }
    const item = await this.StudentOnlineExam.findOneBy(where);
    return item;
  }

  /* 
    查找所有考试历史
  */
  async findAll() {
    return this.StudentOnlineExam.find({
      where: { delFlag: 0 },
    });
  }
  /* 
    根据考试ID获取考试历史
  */
  async findAllByExamId(examId) {
    return this.StudentOnlineExam.query(
      `select soe.user_id as id,u.name as name,u.org_id as orgId from student_online_exam soe left join user u on u.id=soe.user_id  where soe.exam_id = ${examId} and soe.del_flag = 0`,
    );
  }
  /**
   * 根据用户和在线考试ID查询用户已考试次数
   * @param userId 用户ID
   * @param onlineExamId 在线考试ID
   * @returns {}
   */
  async checkExamTimes(userId: string, onlineExamId: number) {
    return this.StudentOnlineExam.query(
      `select count(1) as times,creator as userId,online_exam_id  from online_exam_history oeh where creator = '${userId}' and online_exam_id =${onlineExamId} group by creator,online_exam_id`,
    );
  }

  /**
   * 分页查询人工判卷所有考试
   * @param pagingInfo 分页信息
   * @param token 用户token信息需包含userId
   * @returns
   */
  async pagingGradeDetails(
    examId: number,
    pagingInfo: PagingStudentOnlineExamDto,
  ) {
    const { currentPage, pageSize, title } = pagingInfo;

    // console.log(pagingInfo, whereMap);
    try {
      let sql = `select  oeh.exam_id as examId, oeh.exam_paper_id as paperId,
      oeh.creator as userId,max(oeh.id) as historyId ,
      date_format(max(oeh.create_time), '%Y-%m-%d %H:%i:%S') as createTime ,
      FROM_UNIXTIME(max(oeh.report_time)/1000,'%Y-%m-%d %H:%i:%s') as reportTime,
      (max(oeh.report_time) -  unix_timestamp(max(oeh.create_time))*1000) as myDuration,
      max(oeh.report_time) as reportTimestamp,
      oeh.is_grade_paper as isGradePaper,
      scoreSum.userScore as score,
      e.pass_percent as passPercent,
      e.total_score as totalScore,
      round(e.pass_percent *e.total_score /100) as passScore,
      u.username as username,
      u.name as realname,
      e.exam_end_time <now() as isOver
      from online_exam_history oeh 
      inner join (
        select max(id) as id from online_exam_history oeh2 group by oeh2.exam_id ,oeh2.creator 
      ) oehk on oehk.id = oeh.id
      left join exam e on e.id = oeh.exam_id 
      left join (
        select sum(eqr.score) as userScore,eqr.history_id as historyId ,count(1) as reportCount 
        from exam_questions_result eqr where eqr.del_flag = 0 group by eqr.history_id
      ) as scoreSum on scoreSum.historyId=oeh.id
      left join user u on u.id = oeh.creator 
      where e.del_flag =0  and scoreSum.reportCount>0 and oeh.exam_id =${examId} 
      `;
      // and e.grade_paper_mode=1
      let sqlCount = `
        select count(1) as count from (select max(oeh.id) from online_exam_history oeh 
        left join exam e on e.id = oeh.exam_id  
        left join user u on u.id = oeh.creator 
        where e.del_flag =0 and  oeh.exam_id =${examId}
        `;
      //  and e.grade_paper_mode=1
      if (title) {
        sql += ` AND u.username LIKE '%${title}%'`;
        sqlCount += ` AND u.username LIKE '%${title}%'`;
      }

      sqlCount += ` group by oeh.exam_id ,oeh.creator) a`;

      let total = await this.StudentOnlineExam.query(sqlCount);
      total = total.length > 0 ? +total[0].count : 0;
      if (!currentPage) {
        sql += ` group by oeh.exam_id ,oeh.creator order by oeh.create_time desc limit 0,${total}`;
      } else {
        sql += ` group by oeh.exam_id ,oeh.creator order by oeh.create_time desc limit ?,?`;
      }
      const getPagingQuestions = await this.StudentOnlineExam.query(sql, [
        +(currentPage - 1) * pageSize,
        +pageSize,
      ]);
      // console.log(sql);

      return { total, currentPage, pageSize, data: getPagingQuestions };
    } catch (err) {
      throw '分页查询失败，错误详情：' + err;
    }
  }
  /**
   * 分页查询人工判卷所有考试
   * @param pagingInfo 分页信息
   * @param token 用户token信息需包含userId
   * @returns
   */
  async pagingGrade(
    pagingInfo: PagingStudentOnlineExamDto,
    token: TokenDataEntity,
  ) {
    const { currentPage, pageSize, title } = pagingInfo;
    const { userId, roleId } = token;

    // console.log(pagingInfo, whereMap);
    try {
      let sql = `select 
      count(1) as shouldCount,
      ifnull(finishCount.count,0) as finishCount, 
      ifnull(gradedCount.count,0) as gradedCount,
      ifnull(finishCount.count,0) - ifnull(gradedCount.count,0) as ungradedCount,
      soe.exam_id as examId,
      e.grade_paper_mode as gradeMode,
      soe.create_time  as createTime,
      e.title as title,
      date_format(e.exam_start_time,'%Y-%m-%d %H:%i:%S') as examStartTime,
      date_format(e.exam_end_time ,'%Y-%m-%d %H:%i:%S') as examEndTime,
      e.total_score as totalScore,
      e.is_anonymous as isAnonymous,
      round(e.total_score*e.pass_percent /100)  as passScore
      from student_online_exam soe 
      left join exam e on e.id = soe.exam_id 
      left join (
        select count(oehx.examId) as count,oehx.examId
        from (
          select oeh.creator as userId,oeh.exam_id as examId ,max(oeh.id) oid,min(oeh.is_grade_paper) as gra
            from online_exam_history oeh 
            inner join ( select max(oeh2.id) ids from online_exam_history oeh2 group by oeh2.creator , oeh2.exam_id)  c  on c.ids = oeh.id
            group by oeh.creator , oeh.exam_id
          ) oehx 
          where (select count(1) from exam_questions_result eqr where eqr.history_id = oehx.oid)>0
        group by oehx.examId
      ) as finishCount on finishCount.examId=soe.exam_id 
      left join (
        select count(1) as count,oehx.examId 
        from (
          select oeh.creator as userId,oeh.exam_id as examId ,min(oeh.is_grade_paper) as gra
            from online_exam_history oeh 
            inner join ( select max(oeh2.id) ids from online_exam_history oeh2 group by oeh2.creator , oeh2.exam_id)  c  on c.ids = oeh.id
            group by oeh.creator , oeh.exam_id 
          ) oehx 
          where oehx.gra>0
        group by oehx.examId
      ) as gradedCount on gradedCount.examId=soe.exam_id 
      where e.del_flag=0`; // and e.grade_paper_mode =1
      let sqlCount = `
select count(1) as count from (select e.id from exam e  where e.del_flag = 0 `; //and e.grade_paper_mode =1
      if (title) {
        sql += ` AND e.title LIKE '%${title}%'`;
        sqlCount += ` AND e.title LIKE '%${title}%'`;
      }
      if (userId) {
        //  && roleId == 3
        sql += ` AND e.examiner_id = '${userId}'`;
        sqlCount += ` AND e.examiner_id = '${userId}'`;
      }
      if (pagingInfo['year']) {
        sql += ` and date_format(soe.create_time,'%Y') = date_format('${pagingInfo['year']}','%Y') `;
        sqlCount += ` and date_format(e.create_time,'%Y') = date_format('${pagingInfo['year']}','%Y') `;
      }
      sql += ` group by soe.exam_id order by 
      e.create_time desc limit ?,?`;
      sqlCount += ` order by
      e.create_time desc ) a`;

      const getPagingQuestions = await this.StudentOnlineExam.query(sql, [
        +(currentPage - 1) * pageSize,
        +pageSize,
      ]);
      // console.log(sql);
      let total = await this.StudentOnlineExam.query(sqlCount);
      total = total.length > 0 ? +total[0].count : 0;
      return { total, currentPage, pageSize, data: getPagingQuestions };
    } catch (err) {
      throw '分页查询失败，错误详情：' + err;
    }
  }

  /* 
    分页查找考试记录
  */
  async paging(pagingInfo: PagingStudentOnlineExamDto, token: TokenDataEntity) {
    const { currentPage, pageSize, title } = pagingInfo;
    const { userId, roleId } = token;
    type PagingParamsMap = {
      delFlag: number;
      title: any | null;
      userId: string | null;
    };

    // eslint-disable-next-line prefer-const
    let whereMap: PagingParamsMap = {
      delFlag: 0,
      title: null,
      userId: null,
    };
    // console.log(pagingInfo, whereMap);
    /**
     * 别删 - - 有用
     */
    try {
      // let sql = `select
      // soe.id as id,
      // soe.user_id as userId,
      // e.title as title,
      // ec.name as classify,
      // e.exam_desc as examDesc,
      // e.total_score as totalScore,
      // e.pass_percent as passPercent,
      // round(e.pass_percent*e.total_score/100) as successScore,
      // 0 as myScore,
      // e.exam_duration as examDuration,
      // soe.mistakes  as mistakes ,
      // e.exam_times as examTimes,
      // ifnull(oeh2.times,0)  as myTimes,
      // 0 as myDuration,
      // date_format(e.exam_start_time,'%Y-%m-%d %H:%i:%S') as examStartTime ,
      // date_format(e.exam_end_time ,'%Y-%m-%d %H:%i:%S') as examEndTime ,
      // (case
      //   when now()>=e.exam_start_time and now()<=e.exam_end_time
      // then 1 when now()<e.exam_start_time then 0
      // when now()>e.exam_end_time then 2
      // end) as status
      // from student_online_exam soe
      // left join exam e on soe.exam_id = e.id
      // left join exam_classify ec on ec.id=e.classify_id
      // left join (select count(1) as times,oeh.creator as userId,oeh.online_exam_id  from online_exam_history oeh  group by oeh.creator,oeh.online_exam_id ) oeh2
      // on oeh2.userId = soe.user_id and oeh2.online_exam_id = soe.id
      // where
      // soe.del_flag = 0 `;
      let sql = `
      select  
      soe.id as id,
      soe.user_id as userId,
      e.title as title,
      ec.name as classify,
      e.exam_desc as examDesc,
      e.exam_paper_id as paperId,
      e.total_score as totalScore,
      e.pass_percent as passPercent,
      round(e.pass_percent*e.total_score/100) as successScore,
      ifnull(scoreTemp.userScore,0) as myScore,
      e.exam_duration as examDuration,
      ifnull(mistakTable2.mistakes,0)  as mistakmistakeses ,
      e.exam_times as examTimes,
      ifnull(oeh2.times,0)  as myTimes,
      ifnull(durationTable.duration,0) as myDuration,
      date_format(e.exam_start_time,'%Y-%m-%d %H:%i:%S') as examStartTime , 
      date_format(e.exam_end_time ,'%Y-%m-%d %H:%i:%S') as examEndTime , 
      (case 
        when now()>=e.exam_start_time and now()<=e.exam_end_time 
      then 1 when now()<e.exam_start_time then 0 
      when now()>e.exam_end_time then 2
      end) as status
      from student_online_exam soe 
      left join exam e on soe.exam_id = e.id 
      left join exam_classify ec on ec.id=e.classify_id
      left join (select count(1) as times,oeh.creator as userId,oeh.online_exam_id  
      from online_exam_history oeh  group by oeh.creator,oeh.online_exam_id ) oeh2 
      on oeh2.userId = soe.user_id and oeh2.online_exam_id = soe.id
     
      left join (select oeh2.online_exam_id as online_exam_id,oeh2.create_time ct ,ifnull(scoreSum.userScore,0)as userScore  
	from online_exam_history oeh2 left join (
		select sum(eqr.score) as userScore,eqr.history_id as historyId  
		from exam_questions_result eqr where eqr.del_flag = 0 group by eqr.history_id
	) as scoreSum on 
	scoreSum.historyId = oeh2.id  inner join 
	(select max(oehx.create_time) mtime ,oehx.online_exam_id onlineId,max(oehx.id) nid  from online_exam_history oehx group by oehx.online_exam_id ) stb
	on stb.nid = oeh2.id  where oeh2.is_grade_paper =1) as scoreTemp on scoreTemp.online_exam_id = soe.id 

	left join (select oeh2.online_exam_id as online_exam_id ,ifnull(mistakeTable.mistakes,0)as mistakes  
	from online_exam_history oeh2 left join (
		select count(1) as mistakes,eqr2.history_id as historyId   from exam_questions_result eqr2 
	where eqr2.score< eqr2.question_score and eqr2.del_flag = 0
	group by eqr2.history_id
	) as mistakeTable on 
	mistakeTable.historyId = oeh2.id
	inner join (select max(oehx.create_time) mtime ,oehx.online_exam_id onlineId,max(oehx.id) nid  from online_exam_history oehx group by oehx.online_exam_id ) stb
	on stb.nid = oeh2.id  where oeh2.is_grade_paper =1) as mistakTable2 on mistakTable2.online_exam_id = soe.id 
	
	left join (select (oeh.report_time - unix_timestamp(oeh.create_time)*1000)+0 as duration,oeh.online_exam_id   from online_exam_history oeh 
	inner join (select max(oehx.create_time) mtime ,oehx.online_exam_id onlineId,max(oehx.id) nid  from online_exam_history oehx group by oehx.online_exam_id ) stb
	on stb.nid = oeh.id) as durationTable on durationTable.online_exam_id = soe.id

where soe.del_flag = 0 and e.classify_id!=-1 `;
      let sqlCount = `
select count(1) as count from (select  
  soe.id as id,
  soe.user_id as userId,
  e.title as title
  from student_online_exam soe 
  left join exam e on soe.exam_id = e.id 
where soe.del_flag =0`;
      if (title) {
        sql += ` AND e.title LIKE '%${title}%'`;
        sqlCount += ` AND e.title LIKE '%${title}%'`;
      }
      if (userId) {
        //  && roleId == 3
        sql += ` AND soe.user_id = '${userId}'`;
        sqlCount += ` AND soe.user_id = '${userId}'`;
      }
      sql += `
    order by
    soe.id desc limit ?,?`;
      sqlCount += ` order by
      soe.id desc) a`;

      const getPagingQuestions = await this.StudentOnlineExam.query(sql, [
        +(currentPage - 1) * pageSize,
        +pageSize,
      ]);
      // console.log(sql);
      let total = await this.StudentOnlineExam.query(sqlCount);
      total = total.length > 0 ? +total[0].count : 0;
      return { total, currentPage, pageSize, data: getPagingQuestions };
    } catch (err) {
      throw '分页查询失败，错误详情：' + err;
    }
  }
  async update(
    id: number,
    UpdateStudentOnlineExamDto: UpdateStudentOnlineExamDto,
  ) {
    return this.StudentOnlineExam.update(id, UpdateStudentOnlineExamDto);
  }
  /* 
    删除父类型同时删除子类型
  */
  async remove(id: number) {
    if (isNaN(+id) || !id) throw '缺少id';
    await this.StudentOnlineExam.update(id, { delFlag: 1 });
    return true;
  }
  async removeByExamId(examid: number) {
    return await this.StudentOnlineExam.query(`
    update student_online_exam set del_flag=1 where exam_id=${examid}`);
  }
}
