import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import datetime
import random
import requests
import json
from threading import Thread

# ========== 核心逻辑（和之前一样，但稍微调整了输出格式） ==========
class TravelPlanner:
    def __init__(self, destination, start_date, end_date, budget, people, interests):
        self.dest = destination
        self.start = datetime.datetime.strptime(start_date, "%Y-%m-%d")
        self.end = datetime.datetime.strptime(end_date, "%Y-%m-%d")
        self.budget = float(budget)
        self.people = int(people)
        self.interests = interests
        self.days = (self.end - self.start).days + 1

    def generate_itinerary(self):
        activities_pool = {
            "美食": ["火锅店探店", "夜市小吃巡礼", "早茶体验", "米其林餐厅", "本地菜市场"],
            "文化": ["博物馆参观", "历史街区漫步", "寺庙祈福", "非遗手作体验", "看一场地方戏"],
            "自然": ["公园野餐", "爬山观景", "湖边散步", "植物园游览", "观鸟活动"],
            "购物": ["商业街逛街", "特产商店", "奥特莱斯", "文创市集"],
            "休闲": ["咖啡馆发呆", "书店阅读", "温泉放松", "电影院"]
        }
        selected = []
        for interest in self.interests:
            if interest in activities_pool:
                selected.extend(activities_pool[interest])
        random.shuffle(selected)
        itinerary = {}
        for i in range(self.days):
            day_label = (self.start + datetime.timedelta(days=i)).strftime("%Y-%m-%d")
            day_activities = selected[i*2 : i*2+3] if i*2+3 <= len(selected) else selected[i*2:]
            if not day_activities:
                day_activities = ["自由活动（建议查当地攻略）"]
            itinerary[day_label] = day_activities
        return itinerary

    def budget_breakdown(self):
        total = self.budget
        accommodation = total * 0.35
        food = total * 0.25
        transport = total * 0.20
        entertainment = total * 0.15
        shopping = total * 0.05
        daily_budget = total / self.days
        return {
            "总预算": round(total, 2),
            "住宿 (35%)": round(accommodation, 2),
            "餐饮 (25%)": round(food, 2),
            "交通 (20%)": round(transport, 2),
            "娱乐 (15%)": round(entertainment, 2),
            "购物 (5%)": round(shopping, 2),
            "每日人均预算": round(daily_budget / self.people, 2)
        }

    def get_weather_forecast(self):
        try:
            url = f"https://wttr.in/{self.dest}?format=j1"
            response = requests.get(url, timeout=5)
            data = response.json()
            forecast = []
            for day in data.get("weather", [])[:self.days]:
                date = day["date"]
                temp_max = day["maxtempC"]
                temp_min = day["mintempC"]
                desc = day["hourly"][0]["weatherDesc"][0]["value"]
                forecast.append(f"{date}  {desc}  {temp_min}°C ~ {temp_max}°C")
            return forecast
        except:
            return ["⚠️ 无法获取天气数据，请检查网络或城市名称"]

    def full_plan(self):
        return {
            "itinerary": self.generate_itinerary(),
            "budget": self.budget_breakdown(),
            "weather": self.get_weather_forecast(),
            "days": self.days,
            "destination": self.dest,
            "people": self.people
        }

# ========== 图形界面类 ==========
class TravelApp:
    def __init__(self, root):
        self.root = root
        self.root.title("🧳 智能旅游计划器")
        self.root.geometry("700x750")
        self.root.resizable(True, True)
        
        # 设置样式
        style = ttk.Style()
        style.theme_use('clam')
        
        # ---------- 输入区域 ----------
        main_frame = ttk.Frame(root, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题
        title = ttk.Label(main_frame, text="✈️ 一键生成你的专属旅行计划", font=('Arial', 16, 'bold'))
        title.pack(pady=10)
        
        # 表单
        form_frame = ttk.LabelFrame(main_frame, text="📝 填写旅行信息", padding="15")
        form_frame.pack(fill=tk.X, pady=10)
        
        # 目的地
        ttk.Label(form_frame, text="目的地:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.dest_entry = ttk.Entry(form_frame, width=20)
        self.dest_entry.grid(row=0, column=1, pady=5, padx=5)
        self.dest_entry.insert(0, "成都")
        
        # 出发日期
        ttk.Label(form_frame, text="出发日期 (YYYY-MM-DD):").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.start_entry = ttk.Entry(form_frame, width=20)
        self.start_entry.grid(row=1, column=1, pady=5, padx=5)
        self.start_entry.insert(0, "2026-08-10")
        
        # 结束日期
        ttk.Label(form_frame, text="结束日期 (YYYY-MM-DD):").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.end_entry = ttk.Entry(form_frame, width=20)
        self.end_entry.grid(row=2, column=1, pady=5, padx=5)
        self.end_entry.insert(0, "2026-08-14")
        
        # 预算
        ttk.Label(form_frame, text="总预算 (元):").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.budget_entry = ttk.Entry(form_frame, width=20)
        self.budget_entry.grid(row=3, column=1, pady=5, padx=5)
        self.budget_entry.insert(0, "5000")
        
        # 人数
        ttk.Label(form_frame, text="同行人数 (含你):").grid(row=4, column=0, sticky=tk.W, pady=5)
        self.people_entry = ttk.Entry(form_frame, width=20)
        self.people_entry.grid(row=4, column=1, pady=5, padx=5)
        self.people_entry.insert(0, "2")
        
        # 兴趣（多选）
        ttk.Label(form_frame, text="兴趣标签 (按住Ctrl多选):").grid(row=5, column=0, sticky=tk.W, pady=5)
        self.interests_listbox = tk.Listbox(form_frame, selectmode=tk.MULTIPLE, height=4, width=20)
        self.interests_listbox.grid(row=5, column=1, pady=5, padx=5)
        interests = ["美食", "文化", "自然", "购物", "休闲"]
        for item in interests:
            self.interests_listbox.insert(tk.END, item)
        # 默认选中前三个
        for i in range(3):
            self.interests_listbox.selection_set(i)
        
        # 生成按钮
        self.generate_btn = ttk.Button(main_frame, text="🚀 生成旅行计划", command=self.generate_plan)
        self.generate_btn.pack(pady=15)
        
        # 进度提示
        self.status_label = ttk.Label(main_frame, text="💡 点击按钮生成计划", foreground="gray")
        self.status_label.pack()
        
        # ---------- 结果显示区域 ----------
        result_frame = ttk.LabelFrame(main_frame, text="📋 你的旅行计划", padding="10")
        result_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        
        self.result_text = scrolledtext.ScrolledText(result_frame, wrap=tk.WORD, height=20, font=('Consolas', 10))
        self.result_text.pack(fill=tk.BOTH, expand=True)
        
        # 初始显示提示
        self.result_text.insert(tk.END, "👆 填写信息后点击『生成旅行计划』按钮")
        self.result_text.config(state=tk.DISABLED)

    def generate_plan(self):
        # 让生成按钮不可用，防止重复点击
        self.generate_btn.config(state=tk.DISABLED)
        self.status_label.config(text="⏳ 正在生成计划，请稍候...", foreground="orange")
        self.result_text.config(state=tk.NORMAL)
        self.result_text.delete(1.0, tk.END)
        self.result_text.insert(tk.END, "⏳ 加载中...\n")
        self.result_text.config(state=tk.DISABLED)
        
        # 用线程执行耗时操作（网络请求），避免界面卡死
        Thread(target=self._generate_thread).start()
    
    def _generate_thread(self):
        try:
            # 获取输入
            dest = self.dest_entry.get().strip()
            start = self.start_entry.get().strip()
            end = self.end_entry.get().strip()
            budget = self.budget_entry.get().strip()
            people = self.people_entry.get().strip()
            
            # 简单校验
            if not all([dest, start, end, budget, people]):
                raise ValueError("所有字段都必须填写！")
            
            # 获取选中的兴趣
            selected_indices = self.interests_listbox.curselection()
            interests = [self.interests_listbox.get(i) for i in selected_indices]
            if not interests:
                raise ValueError("请至少选择一个兴趣标签！")
            
            # 创建计划器
            planner = TravelPlanner(dest, start, end, budget, people, interests)
            plan = planner.full_plan()
            
            # 格式化输出
            output = []
            output.append("="*60)
            output.append(f"✈️  {plan['days']}天 {plan['destination']} 旅行计划  (人数: {plan['people']})".center(60))
            output.append("="*60)
            
            # 天气
            output.append("\n🌤️  天气前瞻")
            for w in plan["weather"]:
                output.append(f"  {w}")
            
            # 每日行程
            output.append("\n📅 每日行程建议")
            for date, activities in plan["itinerary"].items():
                output.append(f"\n  📍 {date}")
                for idx, act in enumerate(activities, 1):
                    output.append(f"      {idx}. {act}")
            
            # 预算
            output.append("\n💰 预算分配")
            for key, value in plan["budget"].items():
                output.append(f"  {key}: {value} 元")
            
            output.append("\n" + "="*60)
            output.append("💡 天气来自 wttr.in，行程为智能生成，请根据实际调整。")
            output.append("="*60)
            
            final_text = "\n".join(output)
            
            # 更新界面（必须在主线程）
            self.root.after(0, self._update_result, final_text, "✅ 计划生成完成！", "green")
            
        except Exception as e:
            self.root.after(0, self._update_result, f"❌ 出错了：{str(e)}", "❌ 生成失败", "red")
        finally:
            self.root.after(0, self._enable_button)
    
    def _update_result(self, text, status_msg, color):
        self.result_text.config(state=tk.NORMAL)
        self.result_text.delete(1.0, tk.END)
        self.result_text.insert(tk.END, text)
        self.result_text.config(state=tk.DISABLED)
        self.status_label.config(text=status_msg, foreground=color)
    
    def _enable_button(self):
        self.generate_btn.config(state=tk.NORMAL)

# ========== 启动程序 ==========
if __name__ == "__main__":
    root = tk.Tk()
    app = TravelApp(root)
    root.mainloop()