import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { Lesson } from './lesson.entity';
import { CreateLessonDto } from './dto/create-lesson.dto';
import { UpdateLessonDto } from './dto/update-lesson.dto';
import { ReorderItemDto } from '../common/dto/reorder.dto';

@Injectable()
export class LessonsService {
  constructor(
    @InjectRepository(Lesson)
    private readonly lessonsRepo: Repository<Lesson>,
    private readonly dataSource: DataSource,
  ) {}

  async create(dto: CreateLessonDto): Promise<Lesson> {
    const orderIndex = dto.orderIndex ?? (await this.nextOrderIndex(dto.moduleId));
    return this.lessonsRepo.save(this.lessonsRepo.create({ ...dto, orderIndex }));
  }

  findByModule(moduleId: number): Promise<Lesson[]> {
    return this.lessonsRepo.find({
      where: { moduleId },
      relations: ['activities'],
      order: { orderIndex: 'ASC' },
    });
  }

  findById(id: number): Promise<Lesson | null> {
    return this.lessonsRepo.findOne({
      where: { id },
      relations: ['module', 'activities', 'activities.contentBlocks'],
    });
  }

  async update(id: number, dto: UpdateLessonDto): Promise<Lesson | null> {
    await this.lessonsRepo.update(id, dto);
    return this.findById(id);
  }

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

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

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

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