// AI Trip Planner - Логика приложения // Моковые данные для генерации маршрутов const destinations = { beach: { name: 'Пляжный отдых', locations: ['Пляж Золотой', 'Прибрежный бульвар', 'Морской порт', 'Аквапарк', 'Дайвинг-центр'], activities: { food: ['Рыбный ресторан', 'Кафе у моря', 'Ужин на закате'], photo: ['Фотосессия на пляже', 'Маяк для фото', 'Закатная точка'], history: ['Морской музей', 'Старый порт'], art: ['Галерея маринистики'], nightlife: ['Пляжный бар', 'Ночной клуб у моря'], shopping: ['Рынок сувениров', 'ТЦ прибрежный'], sports: ['Водные лыжи', 'Пляжный волейбол', 'Сёрфинг'], relax: ['SPA-центр', 'Массаж на пляже'], adventure: ['Прогулка на катере', 'Снорклинг'], local: ['Рыбацкая деревня', 'Местный рынок'] } }, active: { name: 'Активный отдых', locations: ['Горнолыжный курорт', 'Скалодром', 'Велотропа', 'Парк приключений', 'Река для рафтинга'], activities: { food: ['Горное кафе', 'Ресторан местной кухни', 'Эко-кафе'], photo: ['Панорамная площадка', 'Водопад для фото'], history: ['Краеведческий музей'], art: ['Галерея современного искусства'], nightlife: ['Бар после спорта', 'Лаунж-зона'], shopping: ['Спортивный магазин', 'Сувениры'], sports: ['Скалолазание', 'Рафтинг', 'Велопрогулка', 'Зиплайн', 'Лыжи'], relax: ['Баня после спорта', 'Массаж'], adventure: ['Прыжок с тарзанки', 'Каньонинг', 'Полёт на параплане'], local: ['Горное село', 'Местные традиции'] } }, culture: { name: 'Культурный отдых', locations: ['Исторический центр', 'Музей искусств', 'Театр оперы', 'Старый город', 'Храм'], activities: { food: ['Ресторан высокой кухни', 'Кафе в старом городе', 'Гастро-тур'], photo: ['Архитектурные шедевры', 'Исторические улочки'], history: ['Краеведческий музей', 'Экскурсия по храмам', 'Древние руины'], art: ['Художественный музей', 'Арт-галерея', 'Мастер-класс по искусству'], nightlife: ['Театральная премьера', 'Джаз-клуб'], shopping: ['Антикварный магазин', 'Книжный', 'Галерея сувениров'], sports: ['Прогулка по городу'], relax: ['Чайная церемония', 'Медитация в саду'], adventure: ['Квест по городу', 'Ночная экскурсия'], local: ['Встреча с местными', 'Традиционный ужин'] } }, nature: { name: 'Отдых на природе', locations: ['Национальный парк', 'Озеро', 'Лесной массив', 'Горная река', 'Заповедник'], activities: { food: ['Пикник на природе', 'Кафе у озера', 'Эко-ресторан'], photo: ['Животные в заповеднике', 'Пейзажи', 'Рассвет в горах'], history: ['Музей природы', 'Эко-тропа с информацией'], art: ['Пленэр для рисования'], nightlife: ['Наблюдение за звёздами', 'Костёр под звёздами'], shopping: ['Эко-лавка', 'Местные продукты'], sports: ['Хайкинг', 'Каякинг', 'Наблюдение за птицами', 'Рыбалка'], relax: ['Йога на природе', 'Медитация у озера'], adventure: ['Поход с палатками', 'Сплавление по реке'], local: ['Встреча с егерем', 'Местные легенды'] } } }; const weatherTips = { beach: '☀️ Лучшее время: май-сентябрь. Не забудь солнцезащитный крем и головной убор.', active: '🏔 Погода переменчива в горах. Возьми ветровку и удобную обувь.', culture: '🏛 Идеально в любое время года. Многие музеи работают до 20:00.', nature: '🌲 Бери репелленты и удобную обувь. Весной и осенью особенно красиво.' }; const budgetTips = { low: '💡 Бюджет ограничен? Сосредоточься на бесплатных активностях: прогулки, пляжи, парки.', medium: '💡 Средний бюджет позволяет добавить платные экскурсии и хорошие рестораны.', high: '💡 С таким бюджетом можно позволить VIP-услуги и эксклюзивные впечатления.' }; let currentTrip = null; let selectedInterests = []; // Инициализация document.addEventListener('DOMContentLoaded', () => { initInterestTags(); loadSavedTrips(); }); function initInterestTags() { const tags = document.querySelectorAll('.interest-tag'); tags.forEach(tag => { tag.addEventListener('click', () => { tag.classList.toggle('selected'); const tagName = tag.dataset.tag; if (selectedInterests.includes(tagName)) { selectedInterests = selectedInterests.filter(i => i !== tagName); } else { selectedInterests.push(tagName); } }); }); } function scrollToSection(id) { document.getElementById(id).scrollIntoView({ behavior: 'smooth' }); } function generateTrip() { const budget = parseInt(document.getElementById('budget').value); const days = parseInt(document.getElementById('days').value); const restType = document.getElementById('restType').value; if (!budget || !days) { alert('Пожалуйста, заполните бюджет и количество дней'); return; } if (selectedInterests.length === 0) { selectedInterests = ['food', 'photo', 'relax']; } currentTrip = createRoute(budget, days, restType, selectedInterests); displayRoute(currentTrip); document.getElementById('results').classList.remove('hidden'); scrollToSection('results'); } function createRoute(budget, days, restType, interests) { const dest = destinations[restType]; const trip = { id: Date.now(), date: new Date().toISOString(), budget: budget, days: days, restType: restType, interests: interests, totalSpent: 0, routeDays: [] }; const budgetPerDay = Math.floor(budget / days); const locationBudget = Math.floor(budgetPerDay * 0.4); const foodBudget = Math.floor(budgetPerDay * 0.3); const activityBudget = Math.floor(budgetPerDay * 0.3); for (let day = 1; day <= days; day++) { const dayPlan = { day: day, title: `День ${day}: ${dest.locations[(day - 1) % dest.locations.length]}`, activities: [] }; const morningTime = 9 + Math.floor(Math.random() * 2); const afternoonTime = morningTime + 3; const eveningTime = afternoonTime + 4; const interest1 = interests[day % interests.length]; const interest2 = interests[(day + 1) % interests.length]; const interest3 = interests[(day + 2) % interests.length]; const morningActivity = dest.activities[interest1]?.[0] || 'Прогулка'; const afternoonActivity = dest.activities[interest2]?.[0] || 'Обед'; const eveningActivity = dest.activities[interest3]?.[0] || 'Отдых'; const morningCost = Math.floor(locationBudget * (0.8 + Math.random() * 0.4)); const afternoonCost = Math.floor(foodBudget * (0.8 + Math.random() * 0.4)); const eveningCost = Math.floor(activityBudget * (0.8 + Math.random() * 0.4)); dayPlan.activities.push({ time: `${morningTime}:00`, name: morningActivity, cost: morningCost }); dayPlan.activities.push({ time: `${afternoonTime}:00`, name: afternoonActivity, cost: afternoonCost }); dayPlan.activities.push({ time: `${eveningTime}:00`, name: eveningActivity, cost: eveningCost }); trip.routeDays.push(dayPlan); trip.totalSpent += morningCost + afternoonCost + eveningCost; } trip.totalSpent = Math.min(trip.totalSpent, budget); return trip; } function displayRoute(trip) { const dest = destinations[trip.restType]; document.getElementById('spentAmount').textContent = trip.totalSpent.toLocaleString(); const remaining = trip.budget - trip.totalSpent; document.getElementById('remainingAmount').textContent = remaining.toLocaleString(); const percent = Math.round((trip.totalSpent / trip.budget) * 100); document.getElementById('budgetFill').style.width = percent + '%'; document.getElementById('budgetPercent').textContent = percent + '% использовано'; let tips = '

🌤 По сезону: ' + weatherTips[trip.restType] + '

'; tips += '

💰 По бюджету: ' + getBudgetTip(trip.budget) + '

'; if (trip.interests.length > 0) { const interestNames = trip.interests.map(i => getInterestName(i)).join(', '); tips += '

🎯 По интересам: Маршрут оптимизирован под: ' + interestNames + '

'; } document.getElementById('aiTipsContent').innerHTML = tips; let daysHtml = '
'; daysHtml += '

📅 Программа по дням

'; trip.routeDays.forEach(day => { daysHtml += '
'; daysHtml += '

' + day.title + '

'; day.activities.forEach(activity => { daysHtml += '
'; daysHtml += '' + activity.time + ''; daysHtml += '' + activity.name + ''; daysHtml += '' + activity.cost.toLocaleString() + ' ₸'; daysHtml += '
'; }); daysHtml += '
'; }); daysHtml += '
'; document.getElementById('routeDays').innerHTML = daysHtml; let mapPointsHtml = ''; trip.routeDays.slice(0, 5).forEach((day, index) => { const location = day.title.split(': ')[1] || day.title; mapPointsHtml += ''; mapPointsHtml += ''; mapPointsHtml += 'День ' + day.day + ': ' + location + ''; mapPointsHtml += ''; }); document.getElementById('mapPoints').innerHTML = mapPointsHtml; } function getInterestName(tag) { const names = { food: 'Еда', photo: 'Фото', history: 'История', art: 'Искусство', nightlife: 'Ночная жизнь', shopping: 'Шопинг', sports: 'Спорт', relax: 'Релакс', adventure: 'Приключения', local: 'Местный колорит' }; return names[tag] || tag; } function getBudgetTip(budget) { if (budget < 200000) return budgetTips.low; if (budget < 500000) return budgetTips.medium; return budgetTips.high; } function saveTrip() { if (!currentTrip) return; const saved = JSON.parse(localStorage.getItem('savedTrips') || '[]'); saved.push(currentTrip); localStorage.setItem('savedTrips', JSON.stringify(saved)); alert('Маршрут сохранён!'); loadSavedTrips(); } function loadSavedTrips() { const saved = JSON.parse(localStorage.getItem('savedTrips') || '[]'); const container = document.getElementById('savedTripsList'); if (saved.length === 0) { container.innerHTML = '

Пока нет сохранённых поездок

'; return; } let html = ''; saved.forEach(trip => { const date = new Date(trip.date).toLocaleDateString('ru-RU'); const destName = destinations[trip.restType]?.name || trip.restType; html += '
'; html += '
'; html += '
'; html += '

' + destName + '

'; html += '

' + trip.days + ' дней • ' + trip.budget.toLocaleString() + ' ₸ • ' + date + '

'; html += '
'; html += '
'; html += ''; html += ''; html += '
'; html += '
'; html += '
'; }); container.innerHTML = html; } function showSavedTrips() { scrollToSection('saved'); } function loadTrip(id) { const saved = JSON.parse(localStorage.getItem('savedTrips') || '[]'); const trip = saved.find(t => t.id === id); if (trip) { currentTrip = trip; displayRoute(trip); document.getElementById('results').classList.remove('hidden'); scrollToSection('results'); } } function deleteTrip(id) { if (!confirm('Удалить этот маршрут?')) return; let saved = JSON.parse(localStorage.getItem('savedTrips') || '[]'); saved = saved.filter(t => t.id !== id); localStorage.setItem('savedTrips', JSON.stringify(saved)); loadSavedTrips(); } function clearForm() { document.getElementById('budget').value = ''; document.getElementById('days').value = ''; document.getElementById('restType').value = 'beach'; selectedInterests = []; document.querySelectorAll('.interest-tag').forEach(tag => tag.classList.remove('selected')); document.getElementById('results').classList.add('hidden'); currentTrip = null; } function exportToPDF() { if (!currentTrip) return; const printWindow = window.open('', '_blank'); const content = generateExportContent('text'); printWindow.document.write(` AI Trip Planner - Маршрут ${content} `); printWindow.document.close(); printWindow.print(); } function exportToText() { if (!currentTrip) return; const content = generateExportContent('text'); const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'ai-trip-route-' + new Date().toISOString().slice(0, 10) + '.txt'; a.click(); URL.revokeObjectURL(url); } function generateExportContent(format) { const dest = destinations[currentTrip.restType]; const date = new Date(currentTrip.date).toLocaleDateString('ru-RU'); let content = 'AI TRIP PLANNER\n'; content += '='.repeat(50) + '\n\n'; content += 'Тип отдыха: ' + dest.name + '\n'; content += 'Длительность: ' + currentTrip.days + ' дней(я)\n'; content += 'Бюджет: ' + currentTrip.budget.toLocaleString() + ' ₸\n'; content += 'Дата создания: ' + date + '\n'; content += 'Интересы: ' + currentTrip.interests.map(i => getInterestName(i)).join(', ') + '\n\n'; content += 'БЮДЖЕТ\n'; content += '-'.repeat(30) + '\n'; content += 'Потрачено: ' + currentTrip.totalSpent.toLocaleString() + ' ₸\n'; content += 'Осталось: ' + (currentTrip.budget - currentTrip.totalSpent).toLocaleString() + ' ₸\n\n'; content += 'МАРШРУТ\n'; content += '-'.repeat(30) + '\n'; currentTrip.routeDays.forEach(day => { content += '\n' + day.title + '\n'; day.activities.forEach(activity => { content += ' ' + activity.time + ' - ' + activity.name + ' (' + activity.cost.toLocaleString() + ' ₸)\n'; }); }); return content; }