import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { Activity } from './activity.entity';
import { CreateActivityDto } from './dto/create-activity.dto';
import { UpdateActivityDto } from './dto/update-activity.dto';
import { ReorderItemDto } from '../common/dto/reorder.dto';

@Injectable()
export class ActivitiesService {
  constructor(
    @InjectRepository(Activity)
    private readonly activitiesRepo: Repository<Activity>,
    private readonly dataSource: DataSource,
  ) {}

  async create(dto: CreateActivityDto): Promise<Activity> {
    const orderIndex = dto.orderIndex ?? (await this.nextOrderIndex(dto.lessonId));
    return this.activitiesRepo.save(this.activitiesRepo.create({ ...dto, orderIndex }));
  }

  findByLesson(lessonId: number): Promise<Activity[]> {
    return this.activitiesRepo.find({
      where: { lessonId },
      relations: ['contentBlocks'],
      order: { orderIndex: 'ASC' },
    });
  }

  findById(id: number): Promise<Activity | null> {
    return this.activitiesRepo.findOne({
      where: { id },
      relations: ['lesson', 'contentBlocks'],
    });
  }

  async update(id: number, dto: UpdateActivityDto): Promise<Activity | null> {
    await this.activitiesRepo.update(id, dto);
    return this.findById(id);
  }

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

  async setStatus(id: number, status: string): Promise<Activity | null> {
    await this.activitiesRepo.update(id, { status });
    return this.findById(id);
  }

  publish(id: number): Promise<Activity | null> {
    return this.setStatus(id, 'PUBLISHED');
  }

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

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