import axios from 'axios';
import { AxiosResponse } from '../types/models';

// Address Checker API
const addressApi = axios.create({
  baseURL: import.meta.env.VITE_ADDRESS_CHECKER_URL || 'http://localhost:9618',
  withCredentials: false, // Address checker doesn't require auth
});

// Response types
export interface TownSuggestion {
  town: string;
  state: string;
  state_id: number;
  customer_count: number;
}

export interface TownSearchResponse {
  ok: boolean;
  suggestions: TownSuggestion[];
  query: string;
}

export interface StreetSuggestion {
  street_name: string;
  full_address: string;
  zip: string;
}

export interface StreetSearchResponse {
  ok: boolean;
  suggestions: StreetSuggestion[];
  town: string;
  state: string;
  query: string;
}

export interface TownStreetInfo {
  town: string;
  state: string;
  street_count: number;
}

export interface TownListResponse {
  ok: boolean;
  towns: TownStreetInfo[];
}

export interface StreetPopulateResponse {
  status: string;
  message: string;
  town: string;
  state: string;
  streets_added: number;
  streets_updated: number;
  total_found: number;
  errors: string[];
}

export interface DeleteStreetsResponse {
  ok: boolean;
  message: string;
  deleted: number;
  town: string;
  state: string;
}

export const addressService = {
  /**
   * Search for towns based on partial input.
   * Returns towns from existing customer data sorted by customer count.
   */
  searchTowns: (query: string, limit: number = 10): Promise<AxiosResponse<TownSearchResponse>> =>
    addressApi.get('/towns/search', {
      params: { q: query, limit }
    }),

  /**
   * Search for streets within a specific town.
   * Returns matching streets from the StreetReference table or customer addresses.
   */
  searchStreets: (
    town: string,
    state: string,
    query: string,
    limit: number = 10
  ): Promise<AxiosResponse<StreetSearchResponse>> =>
    addressApi.get('/streets/search', {
      params: { town, state, q: query, limit }
    }),

  /**
   * List all towns that have streets in the StreetReference table.
   * Used by the admin Street Manager page.
   */
  listTowns: (): Promise<AxiosResponse<TownListResponse>> =>
    addressApi.get('/towns/list'),

  /**
   * Fetch streets from OSM and populate the StreetReference table for a town.
   * Pass clearExisting=true to replace existing streets (fixes bad data).
   */
  populateStreets: (
    town: string,
    state: string,
    clearExisting: boolean = false
  ): Promise<AxiosResponse<StreetPopulateResponse>> =>
    addressApi.post(`/streets/${encodeURIComponent(town)}/${state}`, null, {
      params: { clear_existing: clearExisting }
    }),

  /**
   * Delete all streets for a town from the StreetReference table.
   */
  deleteStreets: (
    town: string,
    state: string
  ): Promise<AxiosResponse<DeleteStreetsResponse>> =>
    addressApi.delete(`/streets/${encodeURIComponent(town)}/${state}`),

  /**
   * Rename a town across all its StreetReference rows.
   */
  renameTown: (
    oldTown: string,
    state: string,
    newTown: string
  ): Promise<AxiosResponse<{ ok: boolean; message: string; updated: number; old_town: string; new_town: string; state: string }>> =>
    addressApi.patch(`/streets/${encodeURIComponent(oldTown)}/${state}/rename`, { new_town: newTown }),

  /**
   * Check if address checker service is available.
   */
  healthCheck: (): Promise<AxiosResponse<{ status: string; db_connected: boolean }>> =>
    addressApi.get('/health'),
};

export default addressService;
