import math
import tkinter as tk
from tkinter import messagebox

# ============ 核心函数：约分 ============
def simplify_frac(zi, mu):
    if mu == 0:
        return None, "分母不能为0"
    if zi == 0:
        return 0, 1
    g = math.gcd(abs(zi), abs(mu))
    new_zi = zi // g
    new_mu = mu // g
    if new_mu < 0:
        new_zi = -new_zi
        new_mu = -new_mu
    return new_zi, new_mu

# ============ 核心函数：假分数转带分数 ============
def to_dai(z, m):
    if abs(z) < abs(m):
        return f"{z}/{m}"
    zheng = z // m
    yu = abs(z) % abs(m)
    if yu == 0:
        return str(zheng)
    # 负数格式优化
    if z < 0:
        return f"-{abs(zheng)}又{yu}/{abs(m)}"
    return f"{zheng}又{yu}/{abs(m)}"

# ============ 小数转分数 ============
def decimal_to_frac(num: str):
    try:
        f = float(num)
        if f.is_integer():
            return int(f), 1
        # 自动判断小数位数
        s = num.strip()
        dot_index = s.find(".")
        bit = len(s) - dot_index - 1
        mu = 10 ** bit
        zi = int(float(s) * mu)
        return simplify_frac(zi, mu)
    except:
        return None, ""

# ============ 计算按钮 ============
def calc():
    mode = radio_var.get()
    try:
        if mode == 1:
            # 分数模式
            zi = int(entry_zi.get())
            mu = int(entry_mu.get())
            res_zi, res_mu = simplify_frac(zi, mu)
            if res_zi is None:
                messagebox.showerror("错误", res_mu)
                return
        else:
            # 小数模式
            dec = entry_dec.get()
            res_zi, res_mu = decimal_to_frac(dec)
            if res_zi is None:
                messagebox.showerror("输入错误", "请输入合法小数！例如：1.25")
                return

        # 显示结果
        lab_simple.config(text=f"✅ 最简分数：{res_zi}/{res_mu}")
        lab_mixed.config(text=f"✅ 带分数：{to_dai(res_zi, res_mu)}")
    except:
        messagebox.showerror("输入错误", "请输入合法整数/小数！")

# ============ 清空 ============
def clear_all():
    entry_zi.delete(0, tk.END)
    entry_mu.delete(0, tk.END)
    entry_dec.delete(0, tk.END)
    lab_simple.config(text="✅ 最简分数：")
    lab_mixed.config(text="✅ 带分数：")

# ============ 复制结果 ============
def copy_result():
    text = lab_simple.cget("text") + "\n" + lab_mixed.cget("text")
    root.clipboard_clear()
    root.clipboard_append(text)
    messagebox.showinfo("复制成功", "结果已复制到剪贴板！")

# ============ 界面UI美化 ============
root = tk.Tk()
root.title("超强版｜分数化简工具（约分+带分数+小数转分数）")
root.geometry("520x340")
root.resizable(False, False)
root.config(bg="#f6f8fa")

# 标题
tk.Label(root, text="📐 专业分数化简工具", font=("黑体", 20, "bold"), bg="#f6f8fa", fg="#222222").pack(pady=12)

# 切换模式
radio_var = tk.IntVar(value=1)
frame_radio = tk.Frame(root, bg="#f6f8fa")
frame_radio.pack()
tk.Radiobutton(frame_radio, text="分数转换", variable=radio_var, value=1, bg="#f6f8fa", font=("微软雅黑",11)).grid(row=0,column=0,padx=20)
tk.Radiobutton(frame_radio, text="小数转分数", variable=radio_var, value=2, bg="#f6f8fa", font=("微软雅黑",11)).grid(row=0,column=1,padx=20)

# 分数输入区
frame1 = tk.Frame(root, bg="#f6f8fa")
frame1.pack(pady=12)
tk.Label(frame1, text="分子：", font=("微软雅黑",12), bg="#f6f8fa").grid(row=0,column=0,padx=5)
entry_zi = tk.Entry(frame1, width=10, font=("微软雅黑",14), bd=2, relief="solid")
entry_zi.grid(row=0,column=1,padx=5)

tk.Label(frame1, text="分母：", font=("微软雅黑",12), bg="#f6f8fa").grid(row=0,column=2,padx=5)
entry_mu = tk.Entry(frame1, width=10, font=("微软雅黑",14), bd=2, relief="solid")
entry_mu.grid(row=0,column=3,padx=5)

# 小数输入区
frame_dec = tk.Frame(root, bg="#f6f8fa")
frame_dec.pack(pady=5)
tk.Label(frame_dec, text="小数：", font=("微软雅黑",12), bg="#f6f8fa").grid(row=0,column=0,padx=5)
entry_dec = tk.Entry(frame_dec, width=25, font=("微软雅黑",14), bd=2, relief="solid")
entry_dec.grid(row=0,column=1,padx=5)

# 按钮区
frame_btn = tk.Frame(root, bg="#f6f8fa")
frame_btn.pack(pady=15)
tk.Button(frame_btn, text="开始计算", command=calc, bg="#27ae60", fg="white", font=("微软雅黑",12), width=9, relief="flat").grid(row=0,column=0,padx=8)
tk.Button(frame_btn, text="一键清空", command=clear_all, bg="#e74c3c", fg="white", font=("微软雅黑",12), width=9, relief="flat").grid(row=0,column=1,padx=8)
tk.Button(frame_btn, text="复制结果", command=copy_result, bg="#3498db", fg="white", font=("微软雅黑",12), width=9, relief="flat").grid(row=0,column=2,padx=8)

# 结果显示
lab_simple = tk.Label(root, text="✅ 最简分数：", font=("微软雅黑",13), bg="#f6f8fa")
lab_simple.pack()
lab_mixed = tk.Label(root, text="✅ 带分数：", font=("微软雅黑",13), bg="#f6f8fa")
lab_mixed.pack(pady=6)

# 底部标注
tk.Label(root, text="支持：正数｜负数｜假分数｜小数｜一键约分", font=("微软雅黑",9), fg="#888888", bg="#f6f8fa").pack(pady=10)

root.mainloop()
