import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CityEntity } from './entities/city.entity';

@Injectable()
export class CityRepository {
  constructor(
    @InjectRepository(CityEntity)
    private readonly cityRepository: Repository<CityEntity>,
  ) {}

  async findAll(take: number, skip: number, search: string) {
    const query = this.cityRepository
      .createQueryBuilder('city')
      .leftJoinAndSelect('city.users', 'user')
      .orderBy('city.name', 'ASC')
      .skip(skip)
      .take(take);

    if (search) {
      query.where('city.name ILIKE :search or city.state ILIKE :search', {
        search: `%${search}%`,
      });
    }

    const [data, count] = await query.getManyAndCount();

    const result = data.map((city) => ({
      ...city,
      user_count: city.users.filter((user) => user.status === 1).length,
    }));

    const response = {
      count,
      result: result.map(({ users, ...rest }) => ({
        ...rest,
        user_count: rest.user_count,
      })),
    };

    return response;
  }

  async findOne(id: string) {
    return this.cityRepository.findOne({ where: { id } });
  }

  async findByCity(name: string, id?: string) {
    const normalizedName = name.toLowerCase();

    const query = this.cityRepository
      .createQueryBuilder('city')
      .where('LOWER(city.name) = :name', { name: normalizedName });

    if (id) {
      query.andWhere('city.id != :id', { id });
    }

    return query.getOne();
  }
}
