#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import tkinter as tk
from tkinter import ttk, messagebox
import datetime

class TemperatureConverterApp:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("温度单位转换器")
        self.root.geometry("1000x900")
        self.root.resizable(False, False)
        
        # 温度单位信息
        self.units = {
            'C': {
                'name': '摄氏度',
                'symbol': '°C',
                'description': '摄氏温标，水的冰点为0°C，沸点为100°C'
            },
            'F': {
                'name': '华氏度',
                'symbol': '°F',
                'description': '华氏温标，水的冰点为32°F，沸点为212°F'
            },
            'K': {
                'name': '开尔文',
                'symbol': 'K',
                'description': '热力学温标，绝对零度为0K'
            },
            'Re': {
                'name': '列氏度',
                'symbol': '°Ré',
                'description': '列氏温标，水的冰点为0°Ré，沸点为80°Ré'
            },
            'Ro': {
                'name': '罗氏度',
                'symbol': '°Rø',
                'description': '罗默温标，水的冰点为7.5°Rø，沸点为60°Rø'
            },
            'De': {
                'name': '德利尔度',
                'symbol': '°De',
                'description': '德利尔温标，水的沸点为0°De，冰点为150°De'
            },
            'N': {
                'name': '牛顿度',
                'symbol': '°N',
                'description': '牛顿温标，水的冰点为0°N，沸点为33°N'
            },
            'Ra': {
                'name': '兰氏度',
                'symbol': '°Ra',
                'description': '兰金温标，绝对零度为0°Ra'
            }
        }
        
        # 转换函数字典
        self.convert_functions = {
            'C': {
                'C': lambda x: x,
                'F': lambda x: x * 9/5 + 32,
                'K': lambda x: x + 273.15,
                'Re': lambda x: x * 4/5,
                'Ro': lambda x: x * 21/40 + 7.5,
                'De': lambda x: (100 - x) * 3/2,
                'N': lambda x: x * 33/100,
                'Ra': lambda x: (x + 273.15) * 9/5
            },
            'F': {
                'C': lambda x: (x - 32) * 5/9,
                'F': lambda x: x,
                'K': lambda x: (x + 459.67) * 5/9,
                'Re': lambda x: (x - 32) * 4/9,
                'Ro': lambda x: (x - 32) * 7/24 + 7.5,
                'De': lambda x: (212 - x) * 5/6,
                'N': lambda x: (x - 32) * 11/60,
                'Ra': lambda x: x + 459.67
            },
            'K': {
                'C': lambda x: x - 273.15,
                'F': lambda x: x * 9/5 - 459.67,
                'K': lambda x: x,
                'Re': lambda x: (x - 273.15) * 4/5,
                'Ro': lambda x: (x - 273.15) * 21/40 + 7.5,
                'De': lambda x: (373.15 - x) * 3/2,
                'N': lambda x: (x - 273.15) * 33/100,
                'Ra': lambda x: x * 9/5
            },
            'Re': {
                'C': lambda x: x * 5/4,
                'F': lambda x: x * 9/4 + 32,
                'K': lambda x: x * 5/4 + 273.15,
                'Re': lambda x: x,
                'Ro': lambda x: x * 21/32 + 7.5,
                'De': lambda x: (80 - x) * 15/8,
                'N': lambda x: x * 33/80,
                'Ra': lambda x: x * 9/4 + 491.67
            },
            'Ro': {
                'C': lambda x: (x - 7.5) * 40/21,
                'F': lambda x: (x - 7.5) * 24/7 + 32,
                'K': lambda x: (x - 7.5) * 40/21 + 273.15,
                'Re': lambda x: (x - 7.5) * 32/21,
                'Ro': lambda x: x,
                'De': lambda x: (60 - x) * 20/7,
                'N': lambda x: (x - 7.5) * 22/35,
                'Ra': lambda x: (x - 7.5) * 24/7 + 491.67
            },
            'De': {
                'C': lambda x: 100 - x * 2/3,
                'F': lambda x: 212 - x * 6/5,
                'K': lambda x: 373.15 - x * 2/3,
                'Re': lambda x: 80 - x * 8/15,
                'Ro': lambda x: 60 - x * 7/20,
                'De': lambda x: x,
                'N': lambda x: 33 - x * 11/50,
                'Ra': lambda x: 671.67 - x * 6/5
            },
            'N': {
                'C': lambda x: x * 100/33,
                'F': lambda x: x * 60/11 + 32,
                'K': lambda x: x * 100/33 + 273.15,
                'Re': lambda x: x * 80/33,
                'Ro': lambda x: x * 35/22 + 7.5,
                'De': lambda x: (33 - x) * 50/11,
                'N': lambda x: x,
                'Ra': lambda x: x * 60/11 + 491.67
            },
            'Ra': {
                'C': lambda x: (x - 491.67) * 5/9,
                'F': lambda x: x - 459.67,
                'K': lambda x: x * 5/9,
                'Re': lambda x: (x - 491.67) * 4/9,
                'Ro': lambda x: (x - 491.67) * 7/24 + 7.5,
                'De': lambda x: (671.67 - x) * 5/6,
                'N': lambda x: (x - 491.67) * 11/60,
                'Ra': lambda x: x
            }
        }
        
        # 常用温度参考
        self.reference_temps = {
            '绝对零度': {'C': -273.15, 'F': -459.67, 'K': 0},
            '水银凝固点': {'C': -38.83, 'F': -37.89, 'K': 234.32},
            '水冰点': {'C': 0, 'F': 32, 'K': 273.15},
            '室温(典型)': {'C': 25, 'F': 77, 'K': 298.15},
            '人体体温': {'C': 37, 'F': 98.6, 'K': 310.15},
            '水沸点': {'C': 100, 'F': 212, 'K': 373.15},
            '黄金熔点': {'C': 1064, 'F': 1947, 'K': 1337},
            '太阳表面': {'C': 5505, 'F': 9941, 'K': 5778}
        }
        
        # 历史记录
        self.history = []
        
        # 创建界面
        self.setup_ui()
        self.center_window()
    
    def center_window(self):
        """窗口居中"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def setup_ui(self):
        """设置界面"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # ===== 标题 =====
        title_label = ttk.Label(
            main_frame, 
            text="🌡️ 温度单位转换器",
            font=('微软雅黑', 20, 'bold')
        )
        title_label.grid(row=0, column=0, columnspan=3, pady=(0, 15))
        
        # ===== 转换区域 =====
        convert_frame = ttk.LabelFrame(main_frame, text="温度转换", padding="15")
        convert_frame.grid(row=1, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 温度输入
        ttk.Label(convert_frame, text="温度值:", font=('微软雅黑', 11)).grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
        self.temp_var = tk.StringVar(value="100")
        self.temp_entry = ttk.Entry(convert_frame, textvariable=self.temp_var, width=20, font=('微软雅黑', 11))
        self.temp_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        
        # 源单位
        ttk.Label(convert_frame, text="源单位:", font=('微软雅黑', 11)).grid(row=1, column=0, sticky=tk.W, pady=10)
        self.from_var = tk.StringVar()
        self.from_combo = ttk.Combobox(convert_frame, textvariable=self.from_var, width=28, font=('微软雅黑', 11), state='readonly')
        units_list = [f"{code} - {info['name']} ({info['symbol']})" for code, info in self.units.items()]
        self.from_combo['values'] = units_list
        self.from_combo.set("")
        self.from_combo.grid(row=1, column=1, sticky=(tk.W, tk.E))
        
        # 目标单位
        ttk.Label(convert_frame, text="目标单位:", font=('微软雅黑', 11)).grid(row=2, column=0, sticky=tk.W, pady=10)
        self.to_var = tk.StringVar()
        self.to_combo = ttk.Combobox(convert_frame, textvariable=self.to_var, width=28, font=('微软雅黑', 11), state='readonly')
        self.to_combo['values'] = units_list
        self.to_combo.set("")
        self.to_combo.grid(row=2, column=1, sticky=(tk.W, tk.E))
        
        # 按钮框架
        button_frame = ttk.Frame(convert_frame)
        button_frame.grid(row=3, column=0, columnspan=2, pady=15)
        
        # 转换按钮
        self.convert_btn = ttk.Button(
            button_frame, 
            text="🔄 转换", 
            command=self.convert,
            width=12
        )
        self.convert_btn.pack(side=tk.LEFT, padx=5)
        
        # 交换按钮
        self.swap_btn = ttk.Button(
            button_frame, 
            text="⇄ 交换", 
            command=self.swap_units,
            width=12
        )
        self.swap_btn.pack(side=tk.LEFT, padx=5)
        
        # 清空按钮
        self.clear_btn = ttk.Button(
            button_frame, 
            text="🗑️ 清空", 
            command=self.clear_input,
            width=12
        )
        self.clear_btn.pack(side=tk.LEFT, padx=5)
        
        # ===== 结果显示区域 =====
        result_frame = ttk.LabelFrame(main_frame, text="转换结果", padding="10")
        result_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
        
        self.result_text = tk.Text(
            result_frame, 
            height=5, 
            width=65,
            font=('微软雅黑', 11),
            state='disabled',
            bg='#f8f9fa',
            relief=tk.FLAT,
            wrap=tk.WORD
        )
        self.result_text.pack(fill=tk.BOTH, expand=True)
        
        # ===== 常用温度参考 =====
        ref_frame = ttk.LabelFrame(main_frame, text="常用温度参考", padding="10")
        ref_frame.grid(row=3, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 创建参考温度表格
        columns = ('名称', '°C', '°F', 'K')
        self.ref_tree = ttk.Treeview(ref_frame, columns=columns, show='headings', height=5)
        
        for col in columns:
            self.ref_tree.heading(col, text=col)
            self.ref_tree.column(col, width=120)
        
        # 添加数据
        for name, temps in self.reference_temps.items():
            self.ref_tree.insert('', tk.END, values=(
                name,
                f"{temps['C']:.2f}" if isinstance(temps['C'], float) else str(temps['C']),
                f"{temps['F']:.2f}" if isinstance(temps['F'], float) else str(temps['F']),
                f"{temps['K']:.2f}" if isinstance(temps['K'], float) else str(temps['K'])
            ))
        
        self.ref_tree.pack(fill=tk.BOTH, expand=True)
        
        # ===== 历史记录区域 =====
        history_frame = ttk.LabelFrame(main_frame, text="历史记录", padding="10")
        history_frame.grid(row=4, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 历史记录文本框
        text_frame = ttk.Frame(history_frame)
        text_frame.pack(fill=tk.BOTH, expand=True)
        
        self.history_text = tk.Text(
            text_frame,
            height=4,
            width=65,
            font=('微软雅黑', 10),
            state='disabled',
            bg='white',
            relief=tk.SUNKEN,
            wrap=tk.WORD
        )
        self.history_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=self.history_text.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.history_text.config(yscrollcommand=scrollbar.set)
        
        # 历史记录按钮
        hist_btn_frame = ttk.Frame(history_frame)
        hist_btn_frame.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Button(
            hist_btn_frame,
            text="清空历史",
            command=self.clear_history,
            width=12
        ).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(
            hist_btn_frame,
            text="导出历史",
            command=self.export_history,
            width=12
        ).pack(side=tk.LEFT, padx=5)
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(4, weight=1)
        convert_frame.columnconfigure(1, weight=1)
        history_frame.columnconfigure(0, weight=1)
        history_frame.rowconfigure(0, weight=1)
        
        # 绑定回车键
        self.temp_entry.bind('<Return>', lambda e: self.convert())
        
        # 初始显示
        self.convert()
    
    def get_unit_code(self, display_text):
        """从显示文本中提取单位代码"""
        return display_text.split(' - ')[0]
    
    def convert(self):
        """执行温度转换"""
        try:
            # 获取输入
            temp_text = self.temp_var.get().strip()
            if not temp_text:
                messagebox.showwarning("警告", "请输入温度值")
                return
            
            temperature = float(temp_text)
            from_code = self.get_unit_code(self.from_var.get())
            to_code = self.get_unit_code(self.to_var.get())
            
            # 执行转换
            convert_func = self.convert_functions[from_code][to_code]
            result = convert_func(temperature)
            
            # 格式化结果
            from_info = self.units[from_code]
            to_info = self.units[to_code]
            
            # 根据温度范围决定小数位
            if abs(result) >= 1000:
                decimals = 1
            elif abs(result) >= 100:
                decimals = 2
            else:
                decimals = 2
            
            result_text = (
                f"{temperature:,.{decimals}f}{from_info['symbol']} {from_info['name']}\n"
                f"  ↓\n"
                f"{result:,.{decimals}f}{to_info['symbol']} {to_info['name']}\n\n"
                f"📝 换算公式: {from_info['name']} → {to_info['name']}"
            )
            
            # 显示结果
            self.result_text.config(state='normal')
            self.result_text.delete('1.0', tk.END)
            self.result_text.insert('1.0', result_text)
            self.result_text.config(state='disabled')
            
            # 添加到历史记录
            timestamp = datetime.datetime.now().strftime("%H:%M:%S")
            history_entry = f"[{timestamp}] {temperature:,.{decimals}f}{from_info['symbol']} → {result:,.{decimals}f}{to_info['symbol']}"
            self.history.append(history_entry)
            self.update_history_display()
            
        except ValueError:
            messagebox.showerror("错误", "请输入有效的温度数值")
        except KeyError:
            messagebox.showerror("错误", "不支持的转换组合")
        except Exception as e:
            messagebox.showerror("错误", f"转换失败: {str(e)}")
    
    def swap_units(self):
        """交换源单位和目标单位"""
        from_val = self.from_var.get()
        to_val = self.to_var.get()
        self.from_var.set(to_val)
        self.to_var.set(from_val)
        self.convert()
    
    def clear_input(self):
        """清空输入"""
        self.temp_var.set("")
        self.result_text.config(state='normal')
        self.result_text.delete('1.0', tk.END)
        self.result_text.config(state='disabled')
        self.temp_entry.focus()
    
    def clear_history(self):
        """清空历史记录"""
        if messagebox.askyesno("确认", "确定要清空所有历史记录吗？"):
            self.history.clear()
            self.update_history_display()
    
    def export_history(self):
        """导出历史记录"""
        if not self.history:
            messagebox.showinfo("提示", "没有历史记录可以导出")
            return
        
        try:
            from tkinter import filedialog
            filename = filedialog.asksaveasfilename(
                defaultextension=".txt",
                filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")],
                initialfile=f"温度转换历史_{datetime.datetime.now().strftime('%Y%m%d')}.txt"
            )
            
            if filename:
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write("温度转换历史记录\n")
                    f.write("=" * 50 + "\n")
                    f.write(f"导出时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                    f.write("=" * 50 + "\n\n")
                    for entry in self.history:
                        f.write(entry + "\n")
                messagebox.showinfo("成功", f"历史记录已导出到:\n{filename}")
                
        except Exception as e:
            messagebox.showerror("错误", f"导出失败: {str(e)}")
    
    def update_history_display(self):
        """更新历史记录显示"""
        self.history_text.config(state='normal')
        self.history_text.delete('1.0', tk.END)
        
        # 显示最近的20条记录
        start = max(0, len(self.history) - 20)
        for entry in self.history[start:]:
            self.history_text.insert(tk.END, entry + "\n")
        
        self.history_text.config(state='disabled')
        self.history_text.see(tk.END)
    
    def run(self):
        """运行应用"""
        self.root.mainloop()


def main():
    app = TemperatureConverterApp()
    app.run()


if __name__ == "__main__":
    main()