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

class WeatherApp:
    def __init__(self, root):
        self.root = root
        self.root.title("天气查询小工具")
        self.root.geometry("500x700")
        self.root.resizable(False, False)
        self.root.configure(bg='#e3f2fd')
        
        self.setup_ui()
        
    def setup_ui(self):
        """设置用户界面"""
        # 标题栏
        title_frame = tk.Frame(self.root, bg='#1565c0', height=80)
        title_frame.pack(fill='x')
        title_frame.pack_propagate(False)
        
        tk.Label(title_frame, text="🌤️ 天气查询工具", 
                font=('Microsoft YaHei', 24, 'bold'),
                fg='white', bg='#1565c0').pack(pady=22)
        
        # 搜索区域
        search_frame = tk.Frame(self.root, bg='#e3f2fd')
        search_frame.pack(pady=20, padx=30, fill='x')
        
        tk.Label(search_frame, text="请输入城市名称：", 
                font=('Microsoft YaHei', 11), bg='#e3f2fd', fg='#37474f').pack(anchor='w')
        
        input_frame = tk.Frame(search_frame, bg='#e3f2fd')
        input_frame.pack(fill='x', pady=8)
        
        self.city_entry = tk.Entry(input_frame, font=('Microsoft YaHei', 14),
                                  relief='solid', bd=1, bg='white')
        self.city_entry.pack(side='left', fill='both', expand=True, ipady=6)
        self.city_entry.bind('<Return>', lambda e: self.search_weather())
        self.city_entry.focus()
        
        search_btn = tk.Button(input_frame, text=" 查询 ", font=('Microsoft YaHei', 12, 'bold'),
                              bg='#1565c0', fg='white', padx=15, pady=6,
                              cursor='hand2', relief='flat',
                              activebackground='#0d47a1', activeforeground='white',
                              command=self.search_weather)
        search_btn.pack(side='right', padx=(10, 0))
        
        # 快捷城市
        quick_frame = tk.Frame(search_frame, bg='#e3f2fd')
        quick_frame.pack(fill='x', pady=(10, 0))
        
        tk.Label(quick_frame, text="快捷查询：", 
                font=('Microsoft YaHei', 9), bg='#e3f2fd', fg='#78909c').pack(side='left')
        
        cities = ["北京", "上海", "广州", "深圳", "杭州", "成都", "武汉", "南京"]
        for city in cities:
            btn = tk.Button(quick_frame, text=city, font=('Microsoft YaHei', 9),
                           bg='#bbdefb', fg='#1565c0', padx=8, pady=2,
                           cursor='hand2', relief='flat',
                           activebackground='#1565c0', activeforeground='white',
                           command=lambda c=city: self.quick_search(c))
            btn.pack(side='left', padx=3)
        
        # 天气信息显示区域
        self.info_frame = tk.Frame(self.root, bg='white', relief='solid', bd=1)
        self.info_frame.pack(pady=10, padx=30, fill='both', expand=True)
        
        # 初始提示
        self.show_welcome()
        
        # 状态栏
        self.status_label = tk.Label(self.root, text="就绪", 
                                   font=('Microsoft YaHei', 9), fg='#90a4ae', bg='#e3f2fd')
        self.status_label.pack(pady=(0, 10))
        
    def show_welcome(self):
        """显示欢迎界面"""
        for widget in self.info_frame.winfo_children():
            widget.destroy()
        
        welcome_text = (
            "🌍 欢迎使用天气查询\n\n"
            "请输入城市名称开始查询\n"
            "支持中文城市名\n"
            "如：北京、上海、深圳"
        )
        tk.Label(self.info_frame, text=welcome_text,
                font=('Microsoft YaHei', 13), bg='white',
                fg='#b0bec5', justify='center').pack(expand=True)
    
    def quick_search(self, city):
        self.city_entry.delete(0, 'end')
        self.city_entry.insert(0, city)
        self.search_weather()
        
    def search_weather(self):
        city = self.city_entry.get().strip()
        if not city:
            messagebox.showwarning("提示", "请输入城市名称！")
            return
        
        self.status_label.config(text="正在查询...")
        
        # 清空显示区域
        for widget in self.info_frame.winfo_children():
            widget.destroy()
        
        tk.Label(self.info_frame, text="⏳ 正在查询中，请稍候...",
                font=('Microsoft YaHei', 13), bg='white', fg='#90a4ae').pack(expand=True)
        
        # 线程查询
        thread = threading.Thread(target=self.fetch_weather, args=(city,))
        thread.daemon = True
        thread.start()
        
    def fetch_weather(self, city):
        """获取天气数据 - 使用多个备用接口"""
        # 方法1: 使用 wttr.in (免费，无需API Key)
        try:
            url = f"https://wttr.in/{city}?format=j1&lang=zh"
            resp = requests.get(url, timeout=8, headers={
                'User-Agent': 'Mozilla/5.0'
            })
            if resp.status_code == 200:
                data = resp.json()
                self.root.after(0, lambda: self.display_weather_wttr(data, city))
                self.root.after(0, lambda: self.status_label.config(text="查询成功"))
                return
        except Exception as e:
            print(f"wttr.in 失败: {e}")
        
        # 方法2: 备用接口
        try:
            url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key=test"
            # 注：高德地图API需要自己的Key
        except:
            pass
        
        # 所有方法都失败
        self.root.after(0, lambda: self.show_error(city))
        self.root.after(0, lambda: self.status_label.config(text="查询失败"))
    
    def display_weather_wttr(self, data, city):
        """显示 wttr.in 的天气数据"""
        for widget in self.info_frame.winfo_children():
            widget.destroy()
        
        try:
            current = data['current_condition'][0]
            area = data.get('nearest_area', [{}])[0]
            
            display_name = city
            if area.get('areaName'):
                display_name = area['areaName'][0]['value']
            if area.get('country'):
                display_name += f", {area['country'][0]['value']}"
            
            temp_c = current['temp_C']
            feels_like = current['FeelsLikeC']
            humidity = current['humidity']
            wind_speed = current['windspeedKmph']
            wind_dir = current['winddir16Point']
            weather_desc = current['weatherDesc'][0]['value']
            visibility = current['visibility']
            pressure = current['pressure']
            
            # 今日预报
            today = data['weather'][0]
            max_temp = today['maxtempC']
            min_temp = today['mintempC']
            
            # 根据温度选颜色
            try:
                t = float(temp_c)
                if t >= 30:
                    temp_color = '#d32f2f'
                elif t >= 20:
                    temp_color = '#f57c00'
                elif t >= 10:
                    temp_color = '#1565c0'
                else:
                    temp_color = '#0277bd'
            except:
                temp_color = '#1565c0'
            
            # ---- 布局 ----
            # 城市名
            tk.Label(self.info_frame, text=display_name,
                    font=('Microsoft YaHei', 20, 'bold'), bg='white', fg='#263238').pack(pady=(20, 2))
            
            # 天气描述
            tk.Label(self.info_frame, text=weather_desc,
                    font=('Microsoft YaHei', 14), bg='white', fg='#78909c').pack(pady=2)
            
            # 温度
            temp_frame = tk.Frame(self.info_frame, bg='white')
            temp_frame.pack(pady=10)
            
            tk.Label(temp_frame, text=f"{temp_c}°C",
                    font=('Microsoft YaHei', 52, 'bold'), bg='white', fg=temp_color).pack()
            
            # 最高/最低温
            tk.Label(self.info_frame, 
                    text=f"↑ {max_temp}°C  ↓ {min_temp}°C",
                    font=('Microsoft YaHei', 11), bg='white', fg='#78909c').pack(pady=2)
            
            # 体感温度
            tk.Label(self.info_frame, text=f"体感温度：{feels_like}°C",
                    font=('Microsoft YaHei', 10), bg='white', fg='#90a4ae').pack(pady=(5, 10))
            
            # 分割线
            tk.Frame(self.info_frame, height=1, bg='#e0e0e0').pack(fill='x', padx=30)
            
            # 详细信息
            detail_frame = tk.Frame(self.info_frame, bg='white')
            detail_frame.pack(pady=15, padx=30, fill='x')
            
            details = [
                ("💧 湿度", f"{humidity}%"),
                ("💨 风速", f"{wind_speed} km/h ({wind_dir})"),
                ("🌫️ 能见度", f"{visibility} km"),
                ("🌊 气压", f"{pressure} mb"),
            ]
            
            for label, value in details:
                row = tk.Frame(detail_frame, bg='white')
                row.pack(fill='x', pady=6)
                
                tk.Label(row, text=label, font=('Microsoft YaHei', 11),
                        bg='white', fg='#546e7a').pack(side='left')
                tk.Label(row, text=value, font=('Microsoft YaHei', 11, 'bold'),
                        bg='white', fg='#263238').pack(side='right')
            
            # 未来几天预报
            if len(data.get('weather', [])) > 1:
                tk.Frame(self.info_frame, height=1, bg='#e0e0e0').pack(fill='x', padx=30, pady=(10, 5))
                
                forecast_frame = tk.Frame(self.info_frame, bg='white')
                forecast_frame.pack(pady=5, padx=20, fill='x')
                
                tk.Label(forecast_frame, text="未来几天预报",
                        font=('Microsoft YaHei', 11, 'bold'), bg='white', fg='#37474f').pack(anchor='w')
                
                for day in data['weather'][1:4]:
                    date = day['date']
                    max_t = day['maxtempC']
                    min_t = day['mintempC']
                    desc = day['hourly'][4]['weatherDesc'][0]['value']
                    
                    row = tk.Frame(forecast_frame, bg='#f5f5f5')
                    row.pack(fill='x', pady=3, padx=5)
                    
                    tk.Label(row, text=date, font=('Microsoft YaHei', 10),
                            bg='#f5f5f5', fg='#546e7a', width=12, anchor='w').pack(side='left')
                    tk.Label(row, text=desc, font=('Microsoft YaHei', 10),
                            bg='#f5f5f5', fg='#78909c').pack(side='left', padx=10)
                    tk.Label(row, text=f"{min_t}°~{max_t}°", font=('Microsoft YaHei', 10, 'bold'),
                            bg='#f5f5f5', fg='#1565c0').pack(side='right')
            
            # 更新时间
            now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            tk.Label(self.info_frame, text=f"更新时间：{now}",
                    font=('Microsoft YaHei', 8), bg='white', fg='#b0bec5').pack(pady=10)
            
        except Exception as e:
            print(f"解析数据失败: {e}")
            self.show_error(city)
    
    def show_error(self, city):
        for widget in self.info_frame.winfo_children():
            widget.destroy()
        
        error_text = (
            f"❌ 无法查询到「{city}」的天气信息\n\n"
            "可能的原因：\n"
            "1. 城市名称输入有误\n"
            "2. 网络连接不稳定\n"
            "3. 该城市不在数据库中\n\n"
            "请检查后重试"
        )
        tk.Label(self.info_frame, text=error_text,
                font=('Microsoft YaHei', 11), bg='white',
                fg='#e57373', justify='center').pack(expand=True)
        
        retry_btn = tk.Button(self.info_frame, text="重新查询",
                             font=('Microsoft YaHei', 10), bg='#1565c0', fg='white',
                             padx=20, pady=5, cursor='hand2', relief='flat',
                             command=self.search_weather)
        retry_btn.pack(pady=10)


def main():
    root = tk.Tk()
    # 设置窗口居中
    root.update_idletasks()
    x = (root.winfo_screenwidth() // 2) - (500 // 2)
    y = (root.winfo_screenheight() // 2) - (700 // 2)
    root.geometry(f"500x700+{x}+{y}")
    
    app = WeatherApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()