import { Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { ProjectInfoEntity } from '../entity/info';
import { ProjectPhaseEntity } from '../entity/phase';
import { ProjectTaskEntity } from '../entity/task';
import { ProjectTaskDependencyEntity } from '../entity/task_dependency';
import { ProjectTimeLogEntity } from '../entity/time_log';

/**
 * 项目信息服务
 */
@Provide()
export class ProjectInfoService extends BaseService {
  @InjectEntityModel(ProjectInfoEntity)
  projectInfoEntity: Repository<ProjectInfoEntity>;

  @InjectEntityModel(ProjectPhaseEntity)
  projectPhaseEntity: Repository<ProjectPhaseEntity>;

  @InjectEntityModel(ProjectTaskEntity)
  projectTaskEntity: Repository<ProjectTaskEntity>;

  @InjectEntityModel(ProjectTaskDependencyEntity)
  projectTaskDependencyEntity: Repository<ProjectTaskDependencyEntity>;

  @InjectEntityModel(ProjectTimeLogEntity)
  projectTimeLogEntity: Repository<ProjectTimeLogEntity>;

  private normalizeIds(ids: any): number[] {
    if (Array.isArray(ids)) {
      return ids.map(id => Number(id)).filter(Boolean);
    }
    if (typeof ids === 'string') {
      return ids
        .split(',')
        .map(id => Number(id))
        .filter(Boolean);
    }
    const id = Number(ids);
    return id ? [id] : [];
  }

  /**
   * 重新计算项目进度（由各阶段加权平均）
   */
  async recalcProgress(projectId: number) {
    const phases = await this.projectPhaseEntity.find({
      where: { projectId },
    });
    if (phases.length === 0) {
      await this.projectInfoEntity.update(projectId, { progress: 0 });
      return;
    }
    const total = phases.reduce((sum, p) => sum + p.progress, 0);
    const progress = Math.round(total / phases.length);
    await this.projectInfoEntity.update(projectId, { progress });
  }

  /**
   * 删除项目时级联删除阶段和任务
   */
  async delete(ids: number[]) {
    const projectIds = this.normalizeIds(ids);
    const tasks = projectIds.length
      ? await this.projectTaskEntity.find({
          where: { projectId: In(projectIds) },
          select: ['id'],
        })
      : [];
    const taskIds = tasks.map(task => task.id);

    await super.delete(ids);

    if (taskIds.length > 0) {
      await this.projectTaskDependencyEntity
        .createQueryBuilder()
        .delete()
        .where('taskId IN (:...taskIds) OR dependsOnTaskId IN (:...taskIds)', {
          taskIds,
        })
        .execute();
      await this.projectTimeLogEntity.delete({ taskId: In(taskIds) });
    }

    if (projectIds.length > 0) {
      await this.projectPhaseEntity.delete({ projectId: In(projectIds) });
      await this.projectTaskEntity.delete({ projectId: In(projectIds) });
    }
  }
}
