import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { GalleryEntity } from './entities/gallery.entity';
import {
  applyFiltersToBuilder,
  applySortingToBuilder,
  paginationResult,
} from 'src/utils';
import { CreateGalleryDto } from './dto/create-gallery.dto';
import { UpdateGalleryDto } from './dto/update-gallery.dto';
import { ErrorService } from 'src/error/error.service';
import { getLastDisplayOrder } from 'src/utils/last-display-order';

@Injectable()
export class GalleryService {
  constructor(
    @InjectRepository(GalleryEntity)
    private galleryRepository: Repository<GalleryEntity>,

    private error: ErrorService,
  ) {}

  /**
   * -------------------------------------------------------
   * GET /galleries
   */
  async getAll(page = 1, limit = 20, filters = null, sorts = null) {
    let builder = this.galleryRepository
      .createQueryBuilder('gallery')
      .take(limit)
      .skip((page - 1) * limit);

    if (sorts) {
      builder = applySortingToBuilder(builder, sorts);
    } else {
      builder.orderBy('gallery.displayOrder', 'ASC');
    }

    builder = applyFiltersToBuilder(builder, filters);

    const [items, totalItems] = await builder.getManyAndCount();

    return {
      items,
      pagination: paginationResult(page, limit, totalItems),
    };
  }

  /**
   * -------------------------------------------------------
   * GET /galleries/1
   */
  async getById(id: number) {
    return await this.galleryRepository.findOne(id);
  }

  /**
   * -------------------------------------------------------
   * POST /galleries
   */
  async addGallery(dto: CreateGalleryDto, image: Express.Multer.File) {
    const newGallery = new GalleryEntity();
    for (const key in dto) {
      newGallery[key] = dto[key];
    }

    newGallery.image = `/uploads/galleries/${image.filename}`;
    newGallery.thumbnail = `/uploads/galleries/${image.filename}`;
    newGallery.displayOrder = await getLastDisplayOrder(GalleryEntity.name);

    newGallery.createdAt = new Date();
    newGallery.updatedAt = new Date();

    const { identifiers } = await this.galleryRepository
      .createQueryBuilder()
      .insert()
      .values(newGallery)
      .execute();

    const newGalleryId = identifiers[0].id;
    return await this.getById(newGalleryId);
  }

  /**
   * -------------------------------------------------------
   * PUT /galleries/1
   */
  async updateGallery(
    id: number,
    dto: UpdateGalleryDto,
    image: Express.Multer.File,
  ) {
    if (image) {
      dto.image = `/uploads/galleries/${image.filename}`;
    }

    return await this.galleryRepository
      .createQueryBuilder()
      .update()
      .set({ ...dto, updatedAt: new Date() })
      .where({ id })
      .execute();
  }

  /**
   * -------------------------------------------------------
   * DELETE /galleries/1
   */
  async deleteGallery(id: number) {
    return await this.galleryRepository.delete(id);
  }
}
