import { Injectable } from "@nestjs/common"
import { InjectRepository } from "@nestjs/typeorm"
import { Repository } from "typeorm"
import { City } from "src/modules/city/entities/city.entity"
import { State } from "src/modules/state/entities/state.entity"
import { Country } from "src/modules/country/entities/country.entity"
import { CountryStateCity } from "src/static-data/country-state-city.json"

@Injectable()
export class CitySeedService {
  constructor(
    @InjectRepository(City)
    private readonly cityRepository: Repository<City>,
    @InjectRepository(State)
    private readonly stateRepository: Repository<State>,
    @InjectRepository(Country)
    private readonly countryRepository: Repository<Country>,
  ) {}

  async run() {
    try {
      let successCount = 0
      let skipCount = 0

      // Loop through all countries in JSON
      for (const countryName of Object.keys(CountryStateCity)) {
        // Find or create Country

        let country = await this.countryRepository
          .createQueryBuilder("country")
          .where("LOWER(country.name) = LOWER(:name)", { name: countryName })
          .getOne()

        if (!country) {
          country = await this.countryRepository.save({ name: countryName })
          successCount++
          console.log(`Created Country: ${countryName}`)
        }

        // Loop through states of this country
        const statesArr = CountryStateCity[countryName]

        for (const stateObj of statesArr) {
          const stateName = Object.keys(stateObj)[0]
          const cities = stateObj[stateName]

          // Find or create State

          let state = await this.stateRepository
            .createQueryBuilder("state")
            .where("LOWER(state.name) = LOWER(:name)", { name: stateName })
            .andWhere("state.country_id = :countryId", {
              countryId: country.id,
            })
            .getOne()

          if (!state) {
            state = await this.stateRepository.save({
              name: stateName,
              country_id: country.id,
            })
            successCount++
            console.log(`Created State: ${stateName} in ${countryName}`)
          }

          // Loop through city list
          for (const cityName of cities) {
            const existingCity = await this.cityRepository
              .createQueryBuilder("city")
              .where("LOWER(city.name) = LOWER(:name)", { name: cityName })
              .andWhere("city.state_id = :stateId", { stateId: state.id })
              .andWhere("city.country_id = :countryId", {
                countryId: country.id,
              })
              .getOne()

            if (!existingCity) {
              await this.cityRepository.save({
                name: cityName,
                state_id: state.id,
                country_id: country.id,
              })

              successCount++
              console.log(
                `Created City: ${cityName} (${stateName}, ${countryName})`,
              )
            } else {
              skipCount++
            }
          }

          console.log(`Processed state: ${stateName} (${countryName})`)
        }
      }

      console.log(
        `🌍 Seeding Completed! Created: ${successCount}, Skipped: ${skipCount}`,
      )
    } catch (error) {
      console.error("❌ Error running city seeder:", error)
      throw error
    }
  }
}
