import tkinter as tk
from tkinter import messagebox, scrolledtext
import requests
import json
from datetime import datetime

class WeatherApp:
    def __init__(self, root):
        self.root = root
        self.root.title("天气查询小工具")
        self.root.geometry("500x600")
        self.root.resizable(False, False)
        self.root.configure(bg="#e0f0ff")
        
        # API配置（使用免费的和风天气API，需要注册获取key）
        # 也可以使用其他免费API如：wttr.in、OpenWeatherMap等
        self.api_key = "YOUR_API_KEY"  # 请替换为你的和风天气API key
        self.api_url = "https://devapi.qweather.com/v7/weather/now"
        self.city_lookup_url = "https://geoapi.qweather.com/v2/city/lookup"
        
        # 创建界面组件
        self.create_widgets()
        
    def create_widgets(self):
        # 标题
        title_label = tk.Label(self.root, text="天气查询工具", font=("微软雅黑", 20, "bold"),
                               bg="#e0f0ff", fg="#2c3e50")
        title_label.pack(pady=15)
        
        # 输入框架
        input_frame = tk.Frame(self.root, bg="#e0f0ff")
        input_frame.pack(pady=10)
        
        # 城市输入
        city_label = tk.Label(input_frame, text="城市名称：", font=("微软雅黑", 12),
                              bg="#e0f0ff", fg="#34495e")
        city_label.grid(row=0, column=0, padx=5)
        
        self.city_entry = tk.Entry(input_frame, font=("微软雅黑", 12), width=20,
                                   relief="solid", bd=1)
        self.city_entry.grid(row=0, column=1, padx=5)
        self.city_entry.bind('<Return>', lambda event: self.get_weather())
        
        # 查询按钮
        self.query_btn = tk.Button(self.root, text="查询天气", command=self.get_weather,
                                   font=("微软雅黑", 12, "bold"), bg="#3498db", fg="white",
                                   padx=20, pady=5, cursor="hand2")
        self.query_btn.pack(pady=10)
        
        # 结果显示区域（使用滚动文本框）
        self.result_text = scrolledtext.ScrolledText(self.root, width=55, height=20,
                                                      font=("微软雅黑", 10), wrap=tk.WORD,
                                                      bg="#ffffff", fg="#2c3e50")
        self.result_text.pack(pady=10, padx=20)
        
        # 状态栏
        self.status_label = tk.Label(self.root, text="请输入城市名称查询天气", font=("微软雅黑", 9),
                                     bg="#e0f0ff", fg="#7f8c8d")
        self.status_label.pack(side=tk.BOTTOM, pady=5)
        
    def get_city_id(self, city_name):
        """获取城市ID"""
        try:
            params = {
                "location": city_name,
                "key": self.api_key
            }
            response = requests.get(self.city_lookup_url, params=params, timeout=10)
            if response.status_code == 200:
                data = response.json()
                if data.get("code") == "200" and data.get("location"):
                    # 返回第一个匹配的城市ID和完整名称
                    location = data["location"][0]
                    return location["id"], location["name"]
            return None, None
        except Exception as e:
            return None, None
    
    def get_weather_data(self, city_id):
        """获取天气数据"""
        try:
            params = {
                "location": city_id,
                "key": self.api_key
            }
            response = requests.get(self.api_url, params=params, timeout=10)
            if response.status_code == 200:
                data = response.json()
                if data.get("code") == "200":
                    return data.get("now", {})
            return None
        except Exception as e:
            return None
    
    def format_weather_display(self, city_name, weather_data):
        """格式化天气信息显示"""
        if not weather_data:
            return "无法获取天气数据"
        
        # 天气现象映射（和风天气的天气代码需要映射，这里简化处理）
        weather_info = f"""
╔════════════════════════════════════════╗
║          实时天气信息                   ║
╠════════════════════════════════════════╣
║  城市：{city_name:<28}║
║  温度：{weather_data.get('temp', 'N/A')}°C{' ' * (30 - len(str(weather_data.get('temp', 'N/A'))))}║
║  体感温度：{weather_data.get('feelsLike', 'N/A')}°C{' ' * (26 - len(str(weather_data.get('feelsLike', 'N/A'))))}║
║  天气：{weather_data.get('text', 'N/A')}{' ' * (30 - len(weather_data.get('text', 'N/A')))}║
║  风向：{weather_data.get('windDir', 'N/A')}{' ' * (30 - len(weather_data.get('windDir', 'N/A')))}║
║  风力等级：{weather_data.get('windScale', 'N/A')}级{' ' * (27 - len(str(weather_data.get('windScale', 'N/A'))))}║
║  风速：{weather_data.get('windSpeed', 'N/A')} km/h{' ' * (26 - len(str(weather_data.get('windSpeed', 'N/A'))))}║
║  湿度：{weather_data.get('humidity', 'N/A')}%{' ' * (30 - len(str(weather_data.get('humidity', 'N/A'))))}║
║  气压：{weather_data.get('pressure', 'N/A')} hPa{' ' * (28 - len(str(weather_data.get('pressure', 'N/A'))))}║
║  能见度：{weather_data.get('vis', 'N/A')} km{' ' * (28 - len(str(weather_data.get('vis', 'N/A'))))}║
╚════════════════════════════════════════╝

更新时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        """
        return weather_info
    
    def get_weather(self):
        """主查询函数"""
        city_name = self.city_entry.get().strip()
        
        if not city_name:
            messagebox.showwarning("输入错误", "请输入城市名称！")
            return
        
        # 清空之前的结果
        self.result_text.delete(1.0, tk.END)
        self.result_text.insert(tk.END, "正在查询天气，请稍候...\n")
        self.status_label.config(text=f"正在查询 {city_name} 的天气...")
        self.query_btn.config(state=tk.DISABLED)
        self.root.update()
        
        try:
            # 获取城市ID
            city_id, full_city_name = self.get_city_id(city_name)
            if not city_id:
                self.result_text.delete(1.0, tk.END)
                self.result_text.insert(tk.END, f"未找到城市：{city_name}\n请检查城市名称是否正确！")
                self.status_label.config(text="查询失败：未找到城市")
                return
            
            # 获取天气数据
            weather_data = self.get_weather_data(city_id)
            if not weather_data:
                self.result_text.delete(1.0, tk.END)
                self.result_text.insert(tk.END, f"无法获取 {full_city_name} 的天气数据\n请稍后重试！")
                self.status_label.config(text="查询失败：无法获取数据")
                return
            
            # 显示结果
            display_text = self.format_weather_display(full_city_name, weather_data)
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, display_text)
            self.status_label.config(text=f"成功获取 {full_city_name} 的最新天气信息")
            
        except requests.exceptions.Timeout:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "网络超时，请检查网络连接后重试！")
            self.status_label.config(text="查询失败：网络超时")
        except requests.exceptions.ConnectionError:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "网络连接失败，请检查网络设置！")
            self.status_label.config(text="查询失败：网络错误")
        except Exception as e:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, f"发生错误：{str(e)}\n请稍后重试！")
            self.status_label.config(text="查询失败：系统错误")
        finally:
            self.query_btn.config(state=tk.NORMAL)

# 备用方案：使用免费的wttr.in API（无需注册）
class SimpleWeatherApp:
    def __init__(self, root):
        self.root = root
        self.root.title("天气查询小工具（简化版）")
        self.root.geometry("500x600")
        self.root.resizable(False, False)
        self.root.configure(bg="#e0f0ff")
        
        self.create_widgets()
    
    def create_widgets(self):
        # 标题
        title_label = tk.Label(self.root, text="天气查询工具（无需注册）", font=("微软雅黑", 18, "bold"),
                               bg="#e0f0ff", fg="#2c3e50")
        title_label.pack(pady=15)
        
        # 输入框架
        input_frame = tk.Frame(self.root, bg="#e0f0ff")
        input_frame.pack(pady=10)
        
        city_label = tk.Label(input_frame, text="城市名称：", font=("微软雅黑", 12),
                              bg="#e0f0ff", fg="#34495e")
        city_label.grid(row=0, column=0, padx=5)
        
        self.city_entry = tk.Entry(input_frame, font=("微软雅黑", 12), width=20,
                                   relief="solid", bd=1)
        self.city_entry.grid(row=0, column=1, padx=5)
        self.city_entry.bind('<Return>', lambda event: self.get_weather())
        
        self.query_btn = tk.Button(self.root, text="查询天气", command=self.get_weather,
                                   font=("微软雅黑", 12, "bold"), bg="#3498db", fg="white",
                                   padx=20, pady=5, cursor="hand2")
        self.query_btn.pack(pady=10)
        
        self.result_text = scrolledtext.ScrolledText(self.root, width=55, height=20,
                                                      font=("微软雅黑", 10), wrap=tk.WORD,
                                                      bg="#ffffff", fg="#2c3e50")
        self.result_text.pack(pady=10, padx=20)
        
        self.status_label = tk.Label(self.root, text="请输入城市名称查询天气（支持中文）", font=("微软雅黑", 9),
                                     bg="#e0f0ff", fg="#7f8c8d")
        self.status_label.pack(side=tk.BOTTOM, pady=5)
    
    def get_weather(self):
        """使用wttr.in API查询天气"""
        city_name = self.city_entry.get().strip()
        
        if not city_name:
            messagebox.showwarning("输入错误", "请输入城市名称！")
            return
        
        self.result_text.delete(1.0, tk.END)
        self.result_text.insert(tk.END, "正在查询天气，请稍候...\n")
        self.status_label.config(text=f"正在查询 {city_name} 的天气...")
        self.query_btn.config(state=tk.DISABLED)
        self.root.update()
        
        try:
            # 使用 wttr.in API（无需API key）
            url = f"https://wttr.in/{city_name}?format=%l:+%c+%t+%w+%h+%p&m"
            response = requests.get(url, timeout=10)
            
            if response.status_code == 200 and response.text.strip():
                weather_info = response.text.strip()
                display_text = f"""
╔════════════════════════════════════════╗
║          实时天气信息                   ║
╠════════════════════════════════════════╣
║  {weather_info:<42}║
╚════════════════════════════════════════╝

说明：
%l - 位置
%c - 天气图标
%t - 温度
%w - 风速
%h - 湿度
%p - 气压

更新时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
                """
                self.result_text.delete(1.0, tk.END)
                self.result_text.insert(tk.END, display_text)
                self.status_label.config(text=f"成功获取 {city_name} 的天气信息")
            else:
                self.result_text.delete(1.0, tk.END)
                self.result_text.insert(tk.END, f"未找到城市：{city_name}\n请尝试使用英文城市名（如：Beijing）")
                self.status_label.config(text="查询失败：未找到城市")
                
        except requests.exceptions.Timeout:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "网络超时，请检查网络连接后重试！")
            self.status_label.config(text="查询失败：网络超时")
        except requests.exceptions.ConnectionError:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "网络连接失败，请检查网络设置！")
            self.status_label.config(text="查询失败：网络错误")
        except Exception as e:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, f"发生错误：{str(e)}\n请稍后重试！")
            self.status_label.config(text="查询失败：系统错误")
        finally:
            self.query_btn.config(state=tk.NORMAL)

# 主程序入口
if __name__ == "__main__":
    root = tk.Tk()
    
    # 选择使用哪个版本：
    # 1. 如果需要详细天气信息，请注册和风天气API（免费）并替换API key
    # 2. 如果只想简单使用，使用SimpleWeatherApp（无需注册）
    
    # 使用简化版（无需API key）
    app = SimpleWeatherApp(root)
    
    # 使用完整版（需要API key）
    # app = WeatherApp(root)
    
    root.mainloop()