import tkinter as tk
from tkinter import ttk

class WeightConverter:
    def __init__(self, root):
        self.root = root
        self.root.title("029. 重量单位转换器")
        self.root.geometry("520x580")
        self.root.resizable(False, False)

        # ===== 基准：千克 =====
        self.units = {
            "毫克(mg)": 1e-6,
            "克(g)": 1e-3,
            "千克(kg)": 1.0,
            "吨(t)": 1000.0,
            "盎司(oz)": 0.0283495,
            "磅(lb)": 0.453592,
            "英石(st)": 6.35029,
            "长吨(lt)": 1016.05,
            "短吨(st)": 907.185,
            "克拉(ct)": 0.0002,
            "格令(gr)": 0.0000647989,
        }

        self.unit_names = list(self.units.keys())

        self.build_ui()
        self.convert()

    # ========== UI ==========
    def build_ui(self):
        # 标题
        tk.Label(
            self.root, text="⚖️ 重量单位转换器",
            font=("微软雅黑", 18, "bold")
        ).pack(pady=12)

        # ===== 输入区 =====
        input_frame = tk.LabelFrame(self.root, text="输入", font=("微软雅黑", 10))
        input_frame.pack(padx=25, pady=5, fill=tk.X)

        tk.Label(input_frame, text="数值：").grid(row=0, column=0, padx=5, pady=10, sticky="e")
        self.value_entry = tk.Entry(input_frame, width=14, font=("Consolas", 12))
        self.value_entry.grid(row=0, column=1, padx=5, pady=10)
        self.value_entry.insert(0, "1")

        tk.Label(input_frame, text="单位：").grid(row=0, column=2, padx=5, pady=10, sticky="e")
        self.from_unit = ttk.Combobox(
            input_frame, values=self.unit_names, width=12, state="readonly"
        )
        self.from_unit.grid(row=0, column=3, padx=5, pady=10)
        self.from_unit.set("千克(kg)")

        self.value_entry.bind("<KeyRelease>", lambda e: self.convert())
        self.from_unit.bind("<<ComboboxSelected>>", lambda e: self.convert())

        # ===== 结果区 =====
        result_frame = tk.LabelFrame(self.root, text="转换结果", font=("微软雅黑", 10))
        result_frame.pack(padx=25, pady=10, fill=tk.BOTH, expand=True)

        # 分类标签
        tk.Label(result_frame, text="▌公制单位", font=("微软雅黑", 9, "bold"),
                 fg="#1565C0").pack(anchor="w", padx=10, pady=(5, 0))

        self.metric_labels = {}
        for name in ["毫克(mg)", "克(g)", "千克(kg)", "吨(t)"]:
            lbl = tk.Label(result_frame, text="", font=("Consolas", 10), anchor="w")
            lbl.pack(anchor="w", padx=20, pady=1)
            self.metric_labels[name] = lbl

        tk.Label(result_frame, text="▌英制单位", font=("微软雅黑", 9, "bold"),
                 fg="#C62828").pack(anchor="w", padx=10, pady=(10, 0))

        self.imperial_labels = {}
        for name in ["盎司(oz)", "磅(lb)", "英石(st)", "长吨(lt)", "短吨(st)"]:
            lbl = tk.Label(result_frame, text="", font=("Consolas", 10), anchor="w")
            lbl.pack(anchor="w", padx=20, pady=1)
            self.imperial_labels[name] = lbl

        tk.Label(result_frame, text="▌其他单位", font=("微软雅黑", 9, "bold"),
                 fg="#2E7D32").pack(anchor="w", padx=10, pady=(10, 0))

        self.other_labels = {}
        for name in ["克拉(ct)", "格令(gr)"]:
            lbl = tk.Label(result_frame, text="", font=("Consolas", 10), anchor="w")
            lbl.pack(anchor="w", padx=20, pady=1)
            self.other_labels[name] = lbl

        # ===== 按钮区 =====
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=10)

        tk.Button(
            btn_frame, text="清空",
            width=12, bg="#FF9800", fg="white",
            font=("微软雅黑", 10),
            command=self.clear
        ).pack(side=tk.LEFT, padx=10)

        tk.Button(
            btn_frame, text="退出",
            width=12, bg="#f44336", fg="white",
            font=("微软雅黑", 10),
            command=self.root.quit
        ).pack(side=tk.LEFT, padx=10)

    # ========== 核心逻辑 ==========
    def convert(self):
        try:
            value = float(self.value_entry.get().strip())
        except ValueError:
            for lbl in {**self.metric_labels, **self.imperial_labels, **self.other_labels}.values():
                lbl.config(text="--")
            return

        from_unit = self.from_unit.get()
        base_value = value * self.units[from_unit]  # 转为千克

        for name, lbl in self.metric_labels.items():
            self._update_label(lbl, name, base_value)

        for name, lbl in self.imperial_labels.items():
            self._update_label(lbl, name, base_value)

        for name, lbl in self.other_labels.items():
            self._update_label(lbl, name, base_value)

    def _update_label(self, lbl, name, base_value):
        converted = base_value / self.units[name]
        if abs(converted) < 1e-6:
            text = f"{name}: {converted:.10e}"
        elif abs(converted) > 1e8:
            text = f"{name}: {converted:.6e}"
        else:
            text = f"{name}: {converted:.6f}"
        lbl.config(text=text)

    def clear(self):
        self.value_entry.delete(0, tk.END)
        self.value_entry.insert(0, "0")
        self.convert()


if __name__ == "__main__":
    root = tk.Tk()
    WeightConverter(root)
    root.mainloop()