import {
  BadRequestException,
  ConflictException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { CreateCourseDto } from './dto/create-course.dto';
import { UpdateCourseDto } from './dto/update-course.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { CourseEntity } from './entities/course.entity';
import { Logs } from 'src/api-logs/entities/logs.entity';
import { EntityManager, Repository } from 'typeorm';
import { CourseRepository } from './courses.repository';
import isValidUuidV4 from 'src/common/uuid validator/uuid-validate';
import { commonMessage } from 'src/common/messages';
import { isEmpty } from 'src/common/helper';
import { lan } from 'src/lan';
import { course } from 'src/common/course-json';

@Injectable()
export class CoursesService {
  constructor(
    @InjectRepository(CourseEntity)
    private readonly courseService: Repository<CourseEntity>,
    private readonly courseRepository: CourseRepository,
  ) {}

  async bulkUpload(manager: EntityManager) {
    const coursesToInsert: any[] = [];

    course.courses.forEach((courseName) => {
      if (!coursesToInsert.some((item) => item.name === courseName)) {
        coursesToInsert.push({ name: courseName });
      }
    });

    await manager.getRepository(CourseEntity).save(coursesToInsert);
  }

  async create(createCourseDto: CreateCourseDto) {
    const createCourse: CreateCourseDto = new CourseEntity();

    const data = await this.courseRepository.findByCourse(createCourseDto.name);

    if (!isEmpty(data)) {
      throw new ConflictException(lan('course.already.exist'));
    } else {
      Object.assign(createCourse, createCourseDto);

      const returnData = await this.courseService.save(createCourse);

      return returnData;
    }
  }

  async findAll(take: number, skip: number, search: string) {
    return await this.courseRepository.findAll(take, skip, search);
  }

  async findOne(id: string) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const course = await this.courseRepository.findOne(id);

    if (isEmpty(course)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    return course;
  }

  async update(id: string, updateCourseDto: UpdateCourseDto) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const courseObj = await this.courseRepository.findOne(id);

    const data = await this.courseRepository.findByCourse(
      updateCourseDto.name,
      id,
    );

    if (isEmpty(courseObj)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    if (courseObj.name) {
      courseObj.name = updateCourseDto.name;
    }

    if (
      updateCourseDto.status !== undefined &&
      updateCourseDto.status !== null
    ) {
      courseObj.status = updateCourseDto.status;
    }

    if (!isEmpty(data)) {
      throw new ConflictException(lan('course.already.exist'));
    }

    await this.courseService.update(id, updateCourseDto);

    return courseObj;
  }

  async remove(id: string) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const city = await this.courseRepository.findOne(id);

    if (isEmpty(city)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    return this.courseService.softDelete(id);
  }
}
