import { Provide } from '@midwayjs/core';
import { BaseService, CoolCommException } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import * as moment from 'moment';
import { PushSorterAttendanceEntity } from '../entity/sorterattendance';
import { BasicdataSorterEntity } from '../../basicdata/entity/sorter';

/**
 * 分拣员签到签退
 */
@Provide()
export class PushSorterAttendanceService extends BaseService {
  @InjectEntityModel(PushSorterAttendanceEntity)
  pushSorterAttendanceEntity: Repository<PushSorterAttendanceEntity>;

  @InjectEntityModel(BasicdataSorterEntity)
  basicdataSorterEntity: Repository<BasicdataSorterEntity>;

  async getSorter(sorterId: string) {
    const sorter = await this.basicdataSorterEntity.findOneBy({
      businessId: String(sorterId || '').trim(),
    });
    if (!sorter || sorter.status !== 0) {
      throw new CoolCommException('分拣员账号不可用');
    }
    return sorter;
  }

  private locationOf(param: any) {
    if (param.longitude == null || param.latitude == null) {
      throw new CoolCommException('缺少定位信息');
    }
    return `${Number(param.longitude)},${Number(param.latitude)}`;
  }

  private today() {
    return moment().format('YYYY-MM-DD');
  }

  private async todayRow(idCard: string) {
    return this.pushSorterAttendanceEntity
      .createQueryBuilder('a')
      .where('a.idCard = :idCard', { idCard })
      .andWhere('a.workDate = :workDate', { workDate: this.today() })
      .getOne();
  }

  async checkIn(param: any) {
    const sorter = await this.getSorter(param.sorterId);
    const loc = this.locationOf(param);
    const now = new Date();
    const workDate = this.today();
    let row = await this.todayRow(sorter.businessId);
    if (row?.checkInTime) {
      throw new CoolCommException('今日已签到');
    }
    if (!row) {
      row = this.pushSorterAttendanceEntity.create({
        idCard: sorter.businessId,
        departmentId: sorter.departmentId,
        uploadTime: now,
        workDate: workDate as any,
        checkInTime: now,
        checkInLocation: loc,
        workHours: 0,
        status: '缺卡',
      });
    } else {
      row.departmentId = sorter.departmentId;
      row.uploadTime = now;
      row.checkInTime = now;
      row.checkInLocation = loc;
    }
    await this.pushSorterAttendanceEntity.save(row);
    return {
      message: '签到成功',
      workDate,
      checkInTime: now,
      checkInLocation: loc,
    };
  }

  async checkOut(param: any) {
    const sorter = await this.getSorter(param.sorterId);
    const loc = this.locationOf(param);
    const now = new Date();
    const workDate = this.today();
    const row = await this.todayRow(sorter.businessId);
    if (!row?.checkInTime) {
      throw new CoolCommException('请先上班签到');
    }
    if (row.checkOutTime) {
      throw new CoolCommException('今日已签退');
    }
    const start = new Date(row.checkInTime).getTime();
    const hours = Math.max(0, (now.getTime() - start) / 3600000);
    row.uploadTime = now;
    row.checkOutTime = now;
    row.checkOutLocation = loc;
    row.workHours = Math.round(hours * 100) / 100;
    row.status = '正常';
    await this.pushSorterAttendanceEntity.save(row);
    return {
      message: '签退成功',
      workDate,
      checkOutTime: now,
      checkOutLocation: loc,
      workHours: row.workHours,
    };
  }
}
