import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
import threading

try:
    import requests
    HAS_REQUESTS = True
except ImportError:
    HAS_REQUESTS = False


RATES = {
    "USD": 1.0, "CNY": 7.18, "EUR": 0.92, "JPY": 157.0, "GBP": 0.79,
    "HKD": 7.81, "KRW": 1380.0, "AUD": 1.52, "CAD": 1.36, "CHF": 0.88,
    "SGD": 1.35, "THB": 36.5, "MYR": 4.7, "RUB": 90.0, "INR": 83.0,
}
RATE_FILE = "rates.json"
MODE = "离线模式"


def load_local_rates():
    global RATES, MODE
    if os.path.exists(RATE_FILE):
        try:
            with open(RATE_FILE, "r", encoding="utf-8") as f:
                d = json.load(f)
                if "USD" in d:
                    RATES.update(d)
                    RATES["USD"] = 1.0
                    MODE = "本地缓存"
        except:
            pass


def save_local_rates():
    with open(RATE_FILE, "w", encoding="utf-8") as f:
        json.dump(RATES, f, ensure_ascii=False, indent=2)


load_local_rates()


def fetch_live_rates():
    if not HAS_REQUESTS:
        return False, "未安装 requests，无法联网"
    try:
        r = requests.get("https://api.frankfurter.dev/v2/rates?base=USD", timeout=8)
        data = r.json()
        nr = {"USD": 1.0}
        for it in data:
            nr[it["quote"]] = float(it["rate"])
        if len(nr) > 5:
            RATES.clear()
            RATES.update(nr)
            save_local_rates()
            return True, f"已更新 {len(nr)} 种货币"
        return False, "接口数据异常"
    except Exception as e:
        return False, f"联网失败：{e}"


root = tk.Tk()
root.title("货币单位转换器")
root.geometry("430x380")
root.resizable(False, False)

amount_var = tk.StringVar(value="100")
from_var = tk.StringVar(value="USD")
to_var = tk.StringVar(value="CNY")
result_var = tk.StringVar(value="—")
status_var = tk.StringVar(value=f"当前模式：{MODE}（内置汇率）")

ttk.Label(root, text="💱 货币单位转换器", font=("Microsoft YaHei", 16, "bold")).pack(pady=10)

f1 = ttk.Frame(root)
f1.pack(pady=4, padx=20, fill="x")
ttk.Label(f1, text="金额：").pack(side="left")
ttk.Entry(f1, textvariable=amount_var, width=16, font=("Microsoft YaHei", 11)).pack(side="left", padx=5)

cl = sorted(RATES.keys())
f2 = ttk.Frame(root)
f2.pack(pady=4, padx=20, fill="x")
ttk.Label(f2, text="从：").pack(side="left")
cb_from = ttk.Combobox(f2, textvariable=from_var, values=cl, state="readonly", width=8)
cb_from.pack(side="left", padx=5)
ttk.Label(f2, text="到：").pack(side="left", padx=(10, 0))
cb_to = ttk.Combobox(f2, textvariable=to_var, values=cl, state="readonly", width=8)
cb_to.pack(side="left", padx=5)

ttk.Label(root, textvariable=result_var, font=("Microsoft YaHei", 14, "bold"), foreground="#1a73e8").pack(pady=12)

btn_frame = ttk.Frame(root)
btn_frame.pack(pady=4)
ttk.Button(btn_frame, text="换算", command=lambda: do_convert()).pack(side="left", padx=6)
ttk.Button(btn_frame, text="交换", command=lambda: swap()).pack(side="left", padx=6)
ttk.Button(btn_frame, text="刷新实时汇率", command=lambda: refresh()).pack(side="left", padx=6)

ttk.Label(root, textvariable=status_var, font=("Microsoft YaHei", 9), foreground="#666").pack(pady=8)


def do_convert():
    try:
        amt = float(amount_var.get())
    except:
        result_var.set("金额无效")
        return
    f, t = from_var.get(), to_var.get()
    if f not in RATES or t not in RATES:
        result_var.set("货币不支持")
        return
    usd = amt / RATES[f]
    out = usd * RATES[t]
    result_var.set(f"{amt:,.2f} {f} = {out:,.4f} {t}")


def swap():
    a, b = from_var.get(), to_var.get()
    from_var.set(b)
    to_var.set(a)
    do_convert()


def refresh():
    status_var.set("正在抓取实时汇率...")
    root.update_idletasks()

    def task():
        ok, msg = fetch_live_rates()
        root.after(0, lambda: (
            status_var.set(f"当前模式：{'实时模式' if ok else MODE}（{msg}）"),
            cl.clear(),
            cl.extend(sorted(RATES.keys())),
            cb_from.configure(values=cl),
            cb_to.configure(values=cl),
            do_convert()
        ))

    threading.Thread(target=task, daemon=True).start()


do_convert()
root.mainloop()