import { BadRequestException, Injectable } from '@nestjs/common';
import { CreateTownDto } from './dto/create-town.dto';
import { Repository } from 'typeorm';
import { Town } from './entities/town.entity';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { StateService } from 'src/state/state.service';
import { TownTraduction } from './entities/town-traduction.entity';
import { CreateTownTraductionDto } from './dto/create-town-trad.dto';
import { LANGUAGES } from 'src/shared/enum/languages.enum';
import { DataSource } from 'typeorm';
import { ServerConstants } from 'src/constants/server.contants';
import { TownResDto } from './dto/town-res.dto';
import { UpdateTownDto } from './dto/update-town.dto';

@Injectable()
export class TownService {
  constructor(
    @InjectRepository(Town) private townRepository: Repository<Town>,
    @InjectRepository(TownTraduction) private townTradRepository: Repository<TownTraduction>,
    @InjectDataSource() private dataSource: DataSource,

    private state: StateService,
  ) {}

  async create(createTownDto: CreateTownDto) {
    const state = await this.state.findOne(createTownDto.state);
    if (!state) throw new BadRequestException('State does not exist');
    const town = await this.townRepository.save({ ...createTownDto, state });
    const createTownTradDtoEN: CreateTownTraductionDto = {
      townId: town.townId,
      language: LANGUAGES.EN,
      description: createTownDto.descriptionEN,
    };

    const createTownTradDtoES: CreateTownTraductionDto = {
      townId: town.townId,
      language: LANGUAGES.ES,
      description: createTownDto.descriptionES,
    };

    await this.townTradRepository.save(createTownTradDtoES);
    await this.townTradRepository.save(createTownTradDtoEN);
  }

  async findTownsByState(stateId: number, lang: string): Promise<TownResDto[]> {
    const ans = await this.dataSource
      .getRepository(TownTraduction)
      .createQueryBuilder('townTrad')
      .leftJoin('townTrad.townId', 'town')
      .select([
        'town.townId AS townId',
        'town.name AS name',
        'town.imageName AS imageName',
        'townTrad.language AS language',
        'townTrad.description AS description',
        'town.state AS stateId',
      ])
      .where('town.state = :stateId', { stateId })
      .andWhere('townTrad.language = :language', { language: lang })
      .andWhere('town.active = true')
      .getRawMany();

    return ans.map((item: TownResDto) => ({
      townId: item.townId,
      name: item.name,
      imageName: `${ServerConstants.HOST}/towns/${item.imageName}`,
      description: item.description,
      stateId: item.stateId,
    }));
  }

  async update(townId: number, updateTownDto: CreateTownDto) {
    const state = await this.state.findOne(updateTownDto.state);
    if (!state) throw new BadRequestException('State does not exist');
    const updateTown: UpdateTownDto = {
      name: updateTownDto.name,
      imageName: updateTownDto.imageName,
      state: state.stateId,
    };
    await this.townRepository.update({ townId }, { ...updateTown, state: state });
    const createTownTradDtoEN: CreateTownTraductionDto = {
      townId: townId,
      language: LANGUAGES.EN,
      description: updateTownDto.descriptionEN,
    };

    const createTownTradDtoES: CreateTownTraductionDto = {
      townId: townId,
      language: LANGUAGES.ES,
      description: updateTownDto.descriptionES,
    };

    await this.townTradRepository.update({ townId, language: LANGUAGES.ES }, createTownTradDtoES);
    await this.townTradRepository.update({ townId, language: LANGUAGES.EN }, createTownTradDtoEN);
  }

  async findOne(idTown: number) {
    const town = await this.townRepository.findOneByOrFail({ townId: idTown });
    const tradEN = await this.townTradRepository.findOneByOrFail({ townId: idTown, language: LANGUAGES.EN });
    const tradES = await this.townTradRepository.findOneByOrFail({ townId: idTown, language: LANGUAGES.ES });
    console.log(town);
    return {
      townId: town.townId,
      name: town.name,
      descriptionEN: tradEN.description,
      descriptionES: tradES.description,
      imageName: `${ServerConstants.HOST}/towns/${town.imageName}`,
      stateId: town.state.stateId,
    };
  }
}
