import { Injectable } from '@nestjs/common';
import { readFileSync } from 'fs';
import path, { join } from 'path';
import { CountyResult, GeoResult } from 'src/models/main.model.js';
import { fileURLToPath } from 'url';
import { City, CountyData, Geo, State } from '../models/server.model.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

@Injectable()
export class GeoService {
  geo: Geo;
  counties: CountyData[];
  constructor() {
    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[]) {
    let 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,
            city: 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, state?: string): Array<{ id: string; name: string; type: 'city' | 'state'; state: string }> {
    const results: Array<{ id: string; name: string; type: 'city' | 'state'; state: string }> = [];

    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.toString(),
          name: state.name,
          type: 'state',
          state: state.state_code,
        });
      }

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

    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.name.localeCompare(b.name);
    });
  }
  getCityWithCoords(state: string, city: string): City {
    return this.geo.states.find(s => s.state_code === state).cities.find(c => c.name === city);
  }
}
