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 { 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 { 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 { 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 ) } }