import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { ProcedureStep } from './procedure-step.entity';
import {
  CreateProcedureStepDto,
  UpdateProcedureStepDto,
} from './dto/procedure-step.dto';
import { ReorderItemDto } from '../common/dto/reorder.dto';

@Injectable()
export class ProcedureStepsService {
  constructor(
    @InjectRepository(ProcedureStep)
    private readonly repo: Repository<ProcedureStep>,
    private readonly dataSource: DataSource,
  ) {}

  async create(dto: CreateProcedureStepDto): Promise<ProcedureStep> {
    const orderIndex = dto.orderIndex ?? (await this.nextOrderIndex(dto.activityId));
    return this.repo.save(this.repo.create({ ...dto, orderIndex }));
  }

  findByActivity(activityId: number): Promise<ProcedureStep[]> {
    return this.repo.find({
      where: { activityId },
      order: { orderIndex: 'ASC', id: 'ASC' },
    });
  }

  findById(id: number): Promise<ProcedureStep | null> {
    return this.repo.findOne({ where: { id } });
  }

  async update(id: number, dto: UpdateProcedureStepDto): Promise<ProcedureStep> {
    const step = await this.findById(id);
    if (!step) throw new NotFoundException('Procedure step not found');
    Object.assign(step, dto);
    return this.repo.save(step);
  }

  async delete(id: number): Promise<boolean> {
    const result = await this.repo.delete(id);
    return (result.affected || 0) > 0;
  }

  async reorder(items: ReorderItemDto[]): Promise<void> {
    await this.dataSource.transaction(async (manager) => {
      for (const item of items) {
        await manager.update(ProcedureStep, item.id, { orderIndex: item.orderIndex });
      }
    });
  }

  private async nextOrderIndex(activityId?: number): Promise<number> {
    if (!activityId) return 0;
    const last = await this.repo.findOne({
      where: { activityId },
      order: { orderIndex: 'DESC' },
    });
    return last ? last.orderIndex + 1 : 0;
  }
}
