# -*- coding: utf-8 -*-
"""
pytcper TCP调试助手 - 主窗口
============================
主窗口:包含 TCP 客户端 / 服务端两个标签页,记忆窗口大小,
菜单栏提供「关于开发者」对话框。
"""

import json
import re
import tkinter as tk
import webbrowser
from tkinter import ttk

from client_tab import ClientTab
from server_tab import ServerTab
from tcp_utils import CONFIG_FILE, __version__


class App(tk.Tk):
    """主窗口:包含 TCP 客户端 / 服务端两个标签页,记忆窗口大小。"""

    def __init__(self):
        super().__init__()
        self.title("pytcper TCP 调试助手 v%s" % __version__)
        self.geometry("900x680")
        self._load_geometry()          # 先恢复上次窗口大小
        self.minsize(1200, 560)         # 增加最小宽度,确保菜单不被裁剪

        nb = ttk.Notebook(self)
        nb.pack(fill="both", expand=True, padx=6, pady=6)
        self.client_tab = ClientTab(nb)
        self.server_tab = ServerTab(nb)
        nb.add(self.client_tab, text="TCP 客户端")
        nb.add(self.server_tab, text="TCP 服务端")

        self.protocol("WM_DELETE_WINDOW", self._on_close)

        # 菜单栏:帮助 → 关于开发者
        menubar = tk.Menu(self)
        help_menu = tk.Menu(menubar, tearoff=False)
        help_menu.add_command(label="关于开发者", command=self._show_about)
        menubar.add_cascade(label="帮助", menu=help_menu)
        self.config(menu=menubar)

    def _show_about(self):
        """显示「关于开发者」对话框。"""
        win = tk.Toplevel(self)
        win.title("关于开发者")
        win.resizable(False, False)
        win.transient(self)
        win.grab_set()
        frame = ttk.Frame(win, padding=16)
        frame.pack(fill="both", expand=True)
        ttk.Label(frame, text="pytcper TCP调试助手 v%s" % __version__,
                  font=("", 12, "bold")).pack()
        ttk.Label(frame, text="版权所有者: micoder").pack(pady=(12, 0))
        link = tk.Label(frame, text="项目地址: https://gitcode.com/micoder/pytcper",
                        fg="#0066CC", cursor="hand2")
        link.pack(pady=(4, 0))
        link.bind("<Button-1>",
                  lambda e: webbrowser.open("https://gitcode.com/micoder/pytcper"))
        ttk.Button(frame, text="关闭", command=win.destroy).pack(pady=(12, 0))

    def _load_geometry(self):
        """从配置文件恢复上次的窗口大小(位置不在任何屏幕内时忽略)。"""
        try:
            with open(CONFIG_FILE, encoding="utf-8") as f:
                cfg = json.load(f)
            geo = cfg.get("geometry")
            if geo and self._geometry_visible(geo):
                self.geometry(geo)
        except (OSError, ValueError, tk.TclError):
            pass

    def _geometry_visible(self, geo):
        """校验几何字符串,且窗口至少部分落在当前屏幕上(避免恢复后不可见)。"""
        try:
            m = re.match(r"^(\d+)x(\d+)([+-]\d+)([+-]\d+)$", geo)
            if not m:
                return True  # 纯尺寸 "WxH" 直接接受
            w, h = int(m.group(1)), int(m.group(2))
            x, y = int(m.group(3)), int(m.group(4))
            sw, sh = self.winfo_screenwidth(), self.winfo_screenheight()
            return x < sw and y < sh and x + w > 0 and y + h > 0
        except (ValueError, tk.TclError):
            return False

    def _save_geometry(self):
        try:
            with open(CONFIG_FILE, "w", encoding="utf-8") as f:
                json.dump({"geometry": self.geometry()}, f)
        except OSError:
            pass

    def _on_close(self):
        self._save_geometry()
        self.client_tab.shutdown()
        self.server_tab.shutdown()
        self.destroy()


def main():
    app = App()
    app.mainloop()