import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { Address } from '@prisma/client'

// İsviçre posta kodları ve şehirleri (örnek veri)
const SWISS_CITIES = [
  { city: 'Zürich', postcode: '8000' },
  { city: 'Basel', postcode: '4000' },
  { city: 'Bern', postcode: '3000' },
  { city: 'Genf', postcode: '1200' },
  { city: 'Lausanne', postcode: '1000' },
  { city: 'Winterthur', postcode: '8400' },
  { city: 'St. Gallen', postcode: '9000' },
  { city: 'Lugano', postcode: '6900' },
]

// Sokak isimleri için örnek son ekler
const STREET_SUFFIXES = [
  'strasse',
  'weg',
  'platz',
  'gasse',
  'allee',
  'boulevard',
  'rue',
  'via',
]

interface NominatimResult {
  place_id: number
  licence: string
  osm_type: string
  osm_id: number
  boundingbox: string[]
  lat: string
  lon: string
  display_name: string
  class: string
  type: string
  importance: number
  address?: {
    house_number?: string
    road?: string
    suburb?: string
    city?: string
    town?: string
    village?: string
    municipality?: string
    state?: string
    postcode?: string
    country?: string
    street?: string
  }
}

interface SearchParams {
  q: string
  type: 'street' | 'number' | 'city'
  street?: string
}

async function searchStreets(query: string): Promise<string[]> {
  try {
    const params = new URLSearchParams({
      q: `${query} ${query.toLowerCase().endsWith('strasse') ? '' : 'strasse'} switzerland`,
      format: 'json',
      addressdetails: '1',
      countrycodes: 'ch',
      limit: '5',
      'accept-language': 'de',
      featuretype: 'street'
    })

    const response = await fetch(
      `https://nominatim.openstreetmap.org/search?${params}`,
      {
        headers: {
          'User-Agent': 'PostaciApp/1.0'
        }
      }
    )

    if (!response.ok) {
      throw new Error('Adres arama servisi şu anda kullanılamıyor')
    }

    const results: NominatimResult[] = await response.json()
    return results
      .filter(result => result.address?.road)
      .map(result => result.address?.road || '')
      .filter((value, index, self) => self.indexOf(value) === index) // Tekrar edenleri kaldır
  } catch (error) {
    console.error('OpenStreetMap API hatası:', error)
    throw error
  }
}

async function searchHouseNumbers(street: string): Promise<string[]> {
  try {
    const params = new URLSearchParams({
      q: `${street} switzerland`,
      format: 'json',
      addressdetails: '1',
      countrycodes: 'ch',
      limit: '15', // Daha fazla sonuç al
      'accept-language': 'de'
    })

    const response = await fetch(
      `https://nominatim.openstreetmap.org/search?${params}`,
      {
        headers: {
          'User-Agent': 'PostaciApp/1.0'
        }
      }
    )

    if (!response.ok) {
      throw new Error('Adres arama servisi şu anda kullanılamıyor')
    }

    const results: NominatimResult[] = await response.json()
    return results
      .filter(result => result.address?.house_number && result.address?.road === street)
      .map(result => result.address?.house_number || '')
      .filter((value, index, self) => self.indexOf(value) === index) // Tekrar edenleri kaldır
      .sort((a, b) => parseInt(a) - parseInt(b)) // Numaraları sırala
  } catch (error) {
    console.error('OpenStreetMap API hatası:', error)
    throw error
  }
}

async function searchCities(query: string): Promise<string[]> {
  try {
    const params = new URLSearchParams({
      q: `${query} switzerland`,
      format: 'json',
      addressdetails: '1',
      countrycodes: 'ch',
      limit: '5',
      'accept-language': 'de',
      featuretype: 'city'
    })

    const response = await fetch(
      `https://nominatim.openstreetmap.org/search?${params}`,
      {
        headers: {
          'User-Agent': 'PostaciApp/1.0'
        }
      }
    )

    if (!response.ok) {
      throw new Error('Adres arama servisi şu anda kullanılamıyor')
    }

    const results: NominatimResult[] = await response.json()
    return results
      .filter(result => result.address?.city || result.address?.postcode)
      .map(result => {
        const city = result.address?.city || ''
        const postcode = result.address?.postcode || ''
        return `${postcode} ${city}`.trim()
      })
      .filter((value, index, self) => self.indexOf(value) === index) // Tekrar edenleri kaldır
  } catch (error) {
    console.error('OpenStreetMap API hatası:', error)
    throw error
  }
}

// Levenshtein mesafesi hesaplama
function levenshteinDistance(a: string, b: string): number {
  if (a.length === 0) return b.length
  if (b.length === 0) return a.length

  const matrix = []

  for (let i = 0; i <= b.length; i++) {
    matrix[i] = [i]
  }

  for (let j = 0; j <= a.length; j++) {
    matrix[0][j] = j
  }

  for (let i = 1; i <= b.length; i++) {
    for (let j = 1; j <= a.length; j++) {
      if (b.charAt(i - 1) === a.charAt(j - 1)) {
        matrix[i][j] = matrix[i - 1][j - 1]
      } else {
        matrix[i][j] = Math.min(
          matrix[i - 1][j - 1] + 1,
          matrix[i][j - 1] + 1,
          matrix[i - 1][j] + 1
        )
      }
    }
  }

  return matrix[b.length][a.length]
}

// Benzerlik oranı hesaplama
function calculateSimilarity(input: string, candidate: string): number {
  const distance = levenshteinDistance(input.toLowerCase(), candidate.toLowerCase())
  const maxLength = Math.max(input.length, candidate.length)
  return 1 - distance / maxLength
}

// Yedek adres verileri
const BACKUP_ADDRESSES = [
  'Luzernstrasse 27, 4552 Derendingen',
  'Luzernstrasse 15, 4552 Derendingen',
  'Luzernstrasse 29, 4552 Derendingen',
  'Luzernstrasse 25, 4552 Derendingen',
  'Luzernstrasse 31, 4552 Derendingen',
  'Luzernstrasse 12, 6003 Luzern',
  'Luzernstrasse 8, 6003 Luzern',
  'Luzernstrasse 16, 6003 Luzern',
  'Bahnhofstrasse 10, 3011 Bern',
  'Hauptstrasse 1, 8001 Zürich',
  'Kirchstrasse 7, 2502 Biel',
  'Marktgasse 8, 4051 Basel',
  'Oberer Graben 12, 9000 St. Gallen',
  'Pilatusstrasse 20, 6003 Luzern',
  'Rue de Lausanne 25, 1800 Vevey',
  'Rue du Mont-Blanc 15, 1201 Genève',
  'Via Nassa 5, 6900 Lugano'
]

export async function GET(request: Request) {
  try {
    const { searchParams } = new URL(request.url)
    const query = searchParams.get('q')

    if (!query || query.length < 2) {
      return NextResponse.json({ error: 'Arama terimi çok kısa' }, { status: 400 })
    }

    // Önce Nominatim API'den ara
    try {
      const params = new URLSearchParams({
        q: `${query} switzerland`,
        format: 'json',
        addressdetails: '1',
        countrycodes: 'ch',
        limit: '5',
        'accept-language': 'de'
      })

      const response = await fetch(
        `https://nominatim.openstreetmap.org/search?${params}`,
        {
          headers: {
            'User-Agent': 'PostaciApp/1.0'
          }
        }
      )

      if (!response.ok) {
        throw new Error('Nominatim API yanıt vermedi')
      }

      const results: NominatimResult[] = await response.json()
      const addresses = results
        .filter(result => result.address?.road || result.display_name)
        .map(result => {
          const street = result.address?.road || ''
          const houseNumber = result.address?.house_number || ''
          const postcode = result.address?.postcode || ''
          const city = result.address?.city || result.address?.town || result.address?.village || ''
          return `${street} ${houseNumber}, ${postcode} ${city}`.trim().replace(/\s+/g, ' ')
        })
        .filter(address => address.length > 0)

      // Eğer Nominatim'den sonuç geldiyse, döndür
      if (addresses.length > 0) {
        return NextResponse.json(addresses)
      }
    } catch (error) {
      console.warn('Nominatim API hatası:', error)
      // Nominatim hatası durumunda yedek adreslere geç
    }

    // Yedek adreslerden benzerlik araması yap
    const sortedAddresses = BACKUP_ADDRESSES
      .map(address => ({
        address,
        similarity: calculateSimilarity(query, address)
      }))
      .sort((a, b) => b.similarity - a.similarity)
      .filter(item => item.similarity > 0.3)
      .map(item => item.address)
      .slice(0, 5)

    if (sortedAddresses.length === 0) {
      return NextResponse.json(
        { error: 'Sonuç bulunamadı' },
        { status: 200 } // 404 yerine 200 dönüyoruz
      )
    }

    return NextResponse.json(sortedAddresses)
  } catch (error) {
    console.error('Adres arama hatası:', error)
    return NextResponse.json(
      { error: 'Adres arama sırasında bir hata oluştu' },
      { status: 200 } // 404 yerine 200 dönüyoruz
    )
  }
} 