import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Visited } from './entities/visited.entity';
import { Repository } from 'typeorm';
import { User } from 'src/user/entities/user.entity';
import { UserService } from 'src/user/user.service';
import { CreateVisitedDto } from './dto/create-visited.dto';
import { Place } from 'src/place/entities/place.entity';
import { PlaceService } from 'src/place/place.service';
import { LANGUAGES } from 'src/shared/enum/languages.enum';
import { VisitedPlacesImageCreator } from './utils/visited_places_image_creator';
import { ServerConstants } from 'src/constants/server.contants';
import { TravelPlace } from 'src/travel-place/entities/travel-place.entity';

@Injectable()
export class VisitedService {
  constructor(
    @InjectRepository(Visited) private visitedRepository: Repository<Visited>,
    private readonly userService: UserService,
    private readonly placeService: PlaceService,
    @InjectRepository(TravelPlace) private travelPlaceRepository: Repository<TravelPlace>,
  ) {}

  async create(createVisitedDto: CreateVisitedDto, email: string) {
    const place: Place = await this.placeService.findOne(createVisitedDto.idPlace);
    const user: User = await this.userService.findOne(email);
    if (!place || !user) throw new BadRequestException('Place or user not found');

    try {
      await this.travelPlaceRepository.update({ place }, { done: true });
    } catch (error) {
      console.log(error);
    }
    await this.visitedRepository.save({ place, user, rating: createVisitedDto.rating });
  }

  async getVisitedByUser(email: string): Promise<Visited[]> {
    const user: User = await this.userService.findOne(email);
    return await this.visitedRepository.find({
      where: { user },
      relations: ['place', 'place.categories'],
    });
  }

  async findAllByUser(email: string) {
    const res = await this.visitedRepository.find({ where: { user: { email } } });
    const visited = res.map((visit: Visited) => {
      return {
        ...visit,
        place: {
          ...visit.place,
          imageName: `${ServerConstants.HOST}/places/${visit.place.imageName}`,
        },
      };
    });
    return visited;
  }

  async getVisitedPlacesImage() {
    // obtener imágenes de los lugares visitados en una ruta
    try {
      const visitedPlaces = (await this.placeService.findAllByTown(1, LANGUAGES.EN))
        .map((place) => place.imageName)
        .slice(0, 5);
      const visitedPlacesImageCreator = new VisitedPlacesImageCreator();
      return await visitedPlacesImageCreator.generateImage(visitedPlaces);
    } catch (error) {
      throw new InternalServerErrorException('Error generating image');
    }
  }
}
