import { Inject, Injectable } from '@nestjs/common';
import { readFileSync } from 'fs';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { join } from 'path';
import { CityAndStateResult, CountyResult, GeoResult, IpInfo, RealIpInfo } from 'src/models/main.model';
import { Logger } from 'winston';
import { City, CountyData, Geo, State } from '../models/server.model';
// const __filename = fileURLToPath(import.meta.url);
// const __dirname = path.dirname(__filename);

@Injectable()
export class GeoService {
  geo: Geo;
  counties: CountyData[];
  constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
    this.loadGeo();
  }
  private loadGeo(): void {
    const filePath = join(__dirname, '../..', 'assets', 'geo.json');
    const rawData = readFileSync(filePath, 'utf8');
    this.geo = JSON.parse(rawData);
    const countiesFilePath = join(__dirname, '../..', 'assets', 'counties.json');
    const rawCountiesData = readFileSync(countiesFilePath, 'utf8');
    this.counties = JSON.parse(rawCountiesData);
  }
  findCountiesStartingWith(prefix: string, states?: string[]) {
    const results: CountyResult[] = [];
    let idCounter = 1;

    this.counties.forEach(stateData => {
      if (!states || states.includes(stateData.state)) {
        stateData.counties.forEach(county => {
          if (county.startsWith(prefix?.toUpperCase())) {
            results.push({
              id: idCounter++,
              name: county,
              state: stateData.state_full,
              state_code: stateData.state,
            });
          }
        });
      }
    });

    return results;
  }
  findCitiesStartingWith(prefix: string, state?: string): GeoResult[] {
    const result: GeoResult[] = [];

    this.geo.states.forEach((state: State) => {
      state.cities.forEach((city: City) => {
        if (city.name.toLowerCase().startsWith(prefix.toLowerCase())) {
          result.push({
            id: city.id,
            name: city.name,
            state: state.state_code,
            //state_code: state.state_code,
            latitude: city.latitude,
            longitude: city.longitude,
          });
        }
      });
    });
    return state ? result.filter(e => e.state.toLowerCase() === state.toLowerCase()) : result;
  }
  findCitiesAndStatesStartingWith(prefix: string): Array<CityAndStateResult> {
    const results: Array<CityAndStateResult> = [];

    const lowercasePrefix = prefix.toLowerCase();

    //for (const country of this.geo) {
    // Suche nach passenden Staaten
    for (const state of this.geo.states) {
      if (state.name.toLowerCase().startsWith(lowercasePrefix)) {
        results.push({
          id: state.id,
          type: 'state',
          content: state,
        });
      }

      // Suche nach passenden Städten
      for (const city of state.cities) {
        if (city.name.toLowerCase().startsWith(lowercasePrefix)) {
          results.push({
            id: city.id,
            type: 'city',
            content: { state: state.state_code, ...city },
          });
        }
      }
      //}
    }

    return results.sort((a, b) => {
      if (a.type === 'state' && b.type === 'city') return -1;
      if (a.type === 'city' && b.type === 'state') return 1;
      return a.content.name.localeCompare(b.content.name);
    });
  }
  getCityWithCoords(state: string, city: string): City {
    return this.geo.states.find(s => s.state_code === state).cities.find(c => c.name === city);
  }
  async fetchIpAndGeoLocation(ipInfo: RealIpInfo): Promise<IpInfo> {
    this.logger.info(`IP:${ipInfo.ip} - CountryCode:${ipInfo.countryCode}`);
    const response = await fetch(`${process.env.IP_INFO_URL}/${ipInfo.ip}/geo?token=${process.env.IP_INFO_TOKEN}`, {
      method: 'GET',
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();

    // Fügen Sie den Ländercode aus Cloudflare hinzu, falls verfügbar
    if (ipInfo.countryCode) {
      data.cloudflareCountry = ipInfo.countryCode;
    }

    return data;
  }
}
