/*
 * @Author: YKH
 * @Date: 2021-12-08 10:26:27
 * @LastEditTime: 2022-10-08 14:01:08
 * @Description:
 * @FilePath: \cool-admin-3.x\cool-admin-midway-master\src\app\modules\shuyou\service\rent_computer.ts
 */
import { Provide, Inject } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from 'midwayjs-cool-core';
import { InjectEntityModel } from '@midwayjs/orm';
import { Repository } from 'typeorm';
import * as _ from 'lodash';
import { ShuyouRentComputerEntity } from '../entity/rent_computer';
import { ShuyouRentComputerUsageEntity } from '../entity/rent_computer_game_record';
import { Utils } from '../../../comm/utils';

/**
 * 租机
 */
@Provide()
export class ShuyouRentComputerService extends BaseService {
  @InjectEntityModel(ShuyouRentComputerEntity)
  ShuyouRentComputerEntity: Repository<ShuyouRentComputerEntity>;
  @InjectEntityModel(ShuyouRentComputerUsageEntity)
  ShuyouRentComputerUsageEntity: Repository<ShuyouRentComputerUsageEntity>;
  @Inject()
  utils: Utils;
  /**
   * 重写新增接口
   */
  async add(param) {
    const existsTask = await this.ShuyouRentComputerEntity.findOne({
      pc_num: param.pc_num,
    });
    if (!_.isEmpty(existsTask)) {
      throw new CoolCommException('已存在相同编号的租机');
    }
    param.createTime = new Date();
    param.updateTime = new Date();
    if (param.price_type == 0) {
      param.rent_price_day = parseFloat(param.rent_price) / 1; // 折算天租金
    } else if (param.price_type == 1) {
      param.rent_price_day = parseFloat(param.rent_price) / 7; // 折算天租金
    } else if (param.price_type == 2) {
      param.rent_price_day = parseFloat(param.rent_price) / 30; // 折算天租金
    }

    // console.log('rent_price_day');
    // console.log(param.rent_price_day);

    await this.updateTaskGame(param);
    return super.add(param);
  }

  /**
   * 更新租机-任务关系
   * @param pc_task
   */
  async updateTaskGame(pc_task) {
    await this.ShuyouRentComputerUsageEntity.delete({ pc_num: pc_task.pc_num });
    if (pc_task.taskIdList) {
      for (const task_id of pc_task.taskIdList) {
        // console.log(task_id)
        await this.ShuyouRentComputerUsageEntity.save({
          pc_num: pc_task.pc_num,
          task_id,
        });
      }
    }
  }

  //表编码格式不一致导致报错解决办法
  //SHOW CREATE TABLE shuyou_rent_computer_usage;
  //ALTER TABLE shuyou_rent_computer_usage DEFAULT CHARACTER SET utf8mb4 COLLATE=utf8mb4_german2_ci;
  // ALTER TABLE shuyou_rent_computer_usage CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci;
  /**
   * 根据ID获得信息
   * @param id
   */
  public async info(id) {
    const info = await this.ShuyouRentComputerEntity.findOne({ id });
    if (info) {
      const taskIds = await this.nativeQuery(
        `select 
          task_id
        from 
          shuyou_rent_computer_usage
        where pc_num = ?`,
        [info.pc_num]
      );
      if (taskIds) {
        info.taskIdList = taskIds.map(e => {
          return e.task_id;
        });
      }
    }
    return info;
  }

  /**
   * 修改
   * @param param 数据
   */
  async update(param) {
    // console.log(param)
    const taskInfo = await this.ShuyouRentComputerEntity.findOne({
      id: param.id,
    });
    if (!taskInfo) {
      throw new CoolCommException('租机不存在');
    }
    if (param.price_type == 0) {
      param.rent_price_day = parseFloat(param.rent_price) / 1; // 折算天租金
    } else if (param.price_type == 1) {
      param.rent_price_day = parseFloat(param.rent_price) / 7; // 折算天租金
    } else if (param.price_type == 2) {
      param.rent_price_day = parseFloat(param.rent_price) / 30; // 折算天租金
    }

    // console.log('rent_price_day');
    // console.log(param.rent_price_day);

    await this.ShuyouRentComputerEntity.save(param);
    await this.updateTaskGame(param);
  }
  /**
   * 重写分页查询
   * @param query
   */
  async page(query) {
    const { pc_num, is_expire, set_meal, shop_id } = query;
    const sql = `
          SELECT
            a.*,
            b.name as shop_name,c.name as rent_person_name,
            GROUP_CONCAT(d.task_id) AS taskIdList,
            GROUP_CONCAT(DISTINCT f.name) AS directorNameList
          FROM
            shuyou_rent_computer a
            LEFT JOIN shuyou_rent_computer_shop b ON a.shop_id = b.id
            LEFT JOIN shuyou_game_director c ON a.rent_person_id = c.id
            LEFT JOIN shuyou_rent_computer_usage d ON a.pc_num = d.pc_num
            LEFT JOIN shuyou_game_task e ON e.id = d.task_id
            LEFT JOIN shuyou_game_director f ON f.id = e.directorId
          WHERE is_offShelf = 0
            ${this.setSql(pc_num, 'and a.pc_num = ?', [pc_num])}
            ${this.setSql(is_expire, 'and a.is_expire = ?', [is_expire])}
            ${this.setSql(set_meal, 'and a.set_meal LIKE ?', [`%${set_meal}%`])}
            ${this.setSql(shop_id, 'and a.shop_id = ?', [shop_id])}
          GROUP BY a.id
        `;
    return this.sqlRenderPage(sql, query);
  }

  /***
   * rentComputerList
   */
  async rentComputerList() {
    const sql = `
          SELECT
            a.id,a.pc_num,
            b.name as shop_name
          FROM
            shuyou_rent_computer a
            LEFT JOIN shuyou_rent_computer_shop b ON a.shop_id = b.id
          WHERE
            is_expire != 1
            and is_offShelf = 0
          ORDER BY a.pc_num
        `;
    return this.nativeQuery(sql);
  }

  /**
   * 更换租机编号
   * @param queryObject
   * @returns
   */
  async replaceNum(queryObject) {
    const info = await this.ShuyouRentComputerEntity.findOne({
      pc_num: queryObject.pc_num_old,
    });
    if (!info) {
      return { code: -1, data: '待更换的租机编号不存在' };
    }
    if (info.is_expire == 1) {
      return { code: -1, data: '待更换的租机已到期' };
    }
    const info2 = await this.ShuyouRentComputerEntity.findOne({
      pc_num: queryObject.pc_num_new,
    });
    if (info2) {
      return { code: -1, data: '要更换的租机编号已存在' };
    }

    var remark =
      this.utils.formatDate(new Date()) +
      ',租机编号' +
      queryObject.pc_num_old +
      '更换为租机编号' +
      queryObject.pc_num_new;
    const res_remark = remark;
    let new_rent_duration = Math.ceil(
      parseInt(
        (Date.parse(queryObject.rent_end) -
          Date.parse(
            this.utils.formatDate(this.utils.getNextDate(new Date(), 1)) +
              ' 00:00:00'
          )) /
          (24 * 60 * 60 * 1000) +
          ''
      )
    );
    let object_new = {
      pc_num: queryObject.pc_num_new,
      pc_name: queryObject.pc_num_new,
      shop_id: queryObject.shop_id,
      rent_duration: new_rent_duration,
      rent_end: queryObject.rent_end,
      set_meal: queryObject.set_meal,
      price_type: queryObject.price_type,
      rent_price: queryObject.rent_price,
      rent_price_day: queryObject.rent_price_day,
      pay_method: queryObject.pay_method,
      rent_person_id: queryObject.rent_person_id,
      rent_start:
        this.utils.formatDate(this.utils.getNextDate(new Date(), 1)) +
        ' 00:00:00',
      rent_price_used: 0,
      remark: remark,
    };
    // console.log(info.remark);
    if (info.remark == '' || info.remark == null) {
      remark = remark;
    } else {
      remark = info.remark + ';' + remark;
    }
    let old_rent_duration = Math.ceil(
      parseInt(
        (Date.parse(this.utils.formatDate(new Date()) + ' 23:59:59') -
          Date.parse(this.utils.formatDate(info.rent_start))) /
          (24 * 60 * 60 * 1000) +
          ''
      )
    );
    let object_old = {
      updateTime: new Date(),
      pc_num: queryObject.pc_num_old,
      rent_end: this.utils.formatDate(new Date()) + ' 23:59:59',
      remark: remark,
      rent_duration: old_rent_duration,
    };

    let updateResult = await this.ShuyouRentComputerEntity.createQueryBuilder()
      .update()
      .set(object_old)
      .where('pc_num = :pc_num and shop_id = :shop_id', {
        pc_num: queryObject.pc_num_old,
        shop_id: queryObject.shop_id,
      })
      .execute();
    if (updateResult.affected >= 1) {
      let insertResult = await this.ShuyouRentComputerEntity.insert(object_new);
      if (insertResult.raw.affectedRows >= 1) {
        this.ShuyouRentComputerUsageEntity.createQueryBuilder()
          .update()
          .set({ pc_num: queryObject.pc_num_new })
          .where('pc_num = :pc_num', {
            pc_num: queryObject.pc_num_old,
          })
          .execute();
      }
    }
    return { code: 1000, data: res_remark };
  }

  /**
   * 退租
   * @param queryObject
   * @returns
   */
  async rentingOut(queryObject) {
    // console.log(queryObject);

    const info = await this.ShuyouRentComputerEntity.findOne({
      id: queryObject.pc_id,
    });
    if (!info) {
      return { code: -1, data: '要退租的机器编号不存在' };
    }
    if (info.is_expire == 1) {
      return { code: -1, data: '要退租的机器已到期' };
    }

    // console.log(info.rent_end);
    // console.log(queryObject.rent_end);
    // console.log(this.utils.formatDateTime(new Date(queryObject.rent_end)));
    let surplus_day = this.utils.dateDiff(
      this.utils.formatDate(new Date(info.rent_end)),
      this.utils.formatDate(new Date(queryObject.rent_end))
    );
    // console.log('剩余天数：' + surplus_day);
    // 2022-09-20,租机编号1退租，剩余时长10天，编号2加5天，编号3加5天
    var remark =
      this.utils.formatDate(queryObject.rent_end) +
      ',租机编号' +
      queryObject.pc_num +
      '退租,剩余' +
      surplus_day +
      '天';
    const addList = queryObject.addList;
    let object_old = {
      updateTime: new Date(),
      rent_end: queryObject.rent_end,
      rent_duration: info.rent_duration - surplus_day,
    };

    let updateResult = await this.ShuyouRentComputerEntity.createQueryBuilder()
      .update()
      .set(object_old)
      .where('id = :id', {
        id: queryObject.pc_id,
      })
      .execute();
    if (updateResult.affected >= 1) {
      await ykhForeach(addList, async (item, index) => {
        // console.log(item.pc_id[0]);
        // console.log(item.add_day);
        const info2 = await this.ShuyouRentComputerEntity.findOne({
          id: item.pc_id[0],
        });
        if (info2) {
          remark =
            remark +
            ',编号' +
            info2.pc_num +
            '加' +
            parseInt(item.add_day) +
            '天';
          let object_new = {
            updateTime: new Date(),
            rent_end: new Date(
              Date.parse(info2.rent_end + '') +
                1 * 24 * 60 * 60 * 1000 * parseInt(item.add_day)
            ),
            rent_duration: info2.rent_duration + parseInt(item.add_day),
          };
          await this.ShuyouRentComputerEntity.createQueryBuilder()
            .update()
            .set(object_new)
            .where('id = :id', {
              id: info2.id,
            })
            .execute();
          // console.log('受影响' + a.affected);
        }
      });
    }
    const res = remark;
    if (info.remark == '' || info.remark == null) {
      remark = remark;
    } else {
      remark = info.remark + ';' + remark;
    }
    await this.ShuyouRentComputerEntity.createQueryBuilder()
      .update()
      .set({
        remark: remark,
      })
      .where('id = :id', {
        id: queryObject.pc_id,
      })
      .execute();
    return { code: 1000, data: res };
  }
  /**
   * 续费
   * @param queryObject
   * @returns
   */
  async renew(queryObject) {
    // console.log(queryObject);

    const info = await this.ShuyouRentComputerEntity.findOne({
      id: queryObject.pc_id,
    });
    if (!info) {
      return { code: -1, data: '要续费的机器编号不存在' };
    }
    // if (info.is_expire == 1) {
    //   return { code: -1, data: '要续费的机器已到期' };
    // }
    // 2022-09-20，租机编号1续费7天，续费至2022-09-27
    var remark =
      this.utils.formatDate(new Date()) +
      ',租机编号' +
      queryObject.pc_num +
      '续费' +
      queryObject.day +
      '天,续费至' +
      this.utils.formatDate(queryObject.rent_renew);

    let is_expire = 0;
    if (Date.parse(queryObject.rent_renew) < new Date().getTime()) {
      is_expire = 1;
    } else if (
      Date.parse(queryObject.rent_renew) - new Date().getTime() <=
      24 * 60 * 60 * 1000
    ) {
      is_expire = 2;
    }
    if (info.remark != '' && info.remark != null) {
      remark = info.remark + ';' + remark;
    }
    let object = {
      updateTime: new Date(),
      rent_end: queryObject.rent_renew,
      rent_duration: info.rent_duration + queryObject.day,
      is_expire: is_expire,
      remark: remark,
    };

    let updateResult = await this.ShuyouRentComputerEntity.createQueryBuilder()
      .update()
      .set(object)
      .where('id = :id', {
        id: queryObject.pc_id,
      })
      .execute();
    if (updateResult.affected >= 1) {
      return { code: 1000, data: remark };
    } else {
      return { code: 1000, data: '该租机无变化' };
    }
  }
  /**
   * 下架
   * @param queryObject
   * @returns
   */
  async offShelf(queryObject) {
    console.log(queryObject);

    const info = await this.ShuyouRentComputerEntity.findOne({
      id: queryObject.pc_id,
    });
    if (!info) {
      return { code: -1, data: '要下架的机器编号不存在' };
    }
    var remark = '下架时间:' + this.utils.formatDate(new Date());

    if (info.remark != '' && info.remark != null) {
      remark = info.remark + ';' + remark;
    }
    let updateResult = await this.ShuyouRentComputerEntity.createQueryBuilder()
      .update()
      .set({
        is_offShelf: 1,
        remark: remark,
        pc_num: 'offShelf_' + info.pc_num,
      })
      .where('id = :id', {
        id: queryObject.pc_id,
      })
      .execute();
    if (updateResult.affected >= 1) {
      return { code: 1000, data: '租机编号' + info.pc_num + '已下架' };
    } else {
      return { code: 1000, data: '该租机无变化' };
    }
  }
  /***
   * 批量插入数据库
   */
  async batchAdd(info: any) {
    let info_text = info;
    const sqlBatchAdd =
      `
        insert 
          IGNORE into 
          shuyou_rent_computer (pc_num,pc_name,rent_person_id,shop_id,set_meal,rent_start,rent_duration,rent_end,price_type,rent_price,rent_price_day,pay_method,is_expire) 
          values 
      ` + info_text;
    // console.log(sqlBatchAdd)
    return await this.nativeQuery(sqlBatchAdd);
  }
}

// foreach加上async/await
const ykhForeach = async (arr, callback) => {
  const length = arr.length;
  const O = Object(arr);
  let k = 0;
  while (k < length) {
    if (k in O) {
      // console.log('doing foreach...');
      const kValue = O[k];
      await callback(kValue, k, O);
    }
    k++;
  }
};
