# coding: utf-8
"""
对话框基础模块

提供对话框的通用工具函数和基类。
"""

import ctypes
import tkinter as tk
from tkinter import ttk
from typing import Optional, Callable

from .toast_constants import DEFAULT_FONT_FAMILY
from . import logger

# DPI 感知设置（与 toast_base.py 保持一致）
try:
    ctypes.windll.shcore.SetProcessDpiAwareness(1)
except (OSError, AttributeError):
    pass


# ============================================================
# 工具函数
# ============================================================

def create_modal_dialog(
    title: str,
    width: int = 600,
    height: int = 400,
    resizable: bool = False,
    withdraw: bool = True
) -> tk.Toplevel:
    """
    创建模态对话框窗口

    Args:
        title: 窗口标题
        width: 窗口宽度（像素）
        height: 窗口高度（像素）
        resizable: 是否允许调整窗口大小
        withdraw: 是否先隐藏窗口（避免闪烁），默认 True

    Returns:
        tkinter Toplevel 窗口对象
    """
    # 创建 Toplevel 窗口
    dialog = tk.Toplevel()
    dialog.title(title)

    # 先隐藏窗口，避免闪烁
    if withdraw:
        dialog.withdraw()

    # 设置窗口大小
    dialog.geometry(f"{width}x{height}")
    dialog.resizable(resizable, resizable)

    # 设置为模态窗口
    dialog.transient()  # 属于主窗口
    dialog.grab_set()   # 捕获焦点，阻止用户操作其他窗口

    # 居中显示
    _center_window(dialog, width, height)

    logger.debug(f"创建模态对话框: {title} ({width}x{height})")

    return dialog


def _center_window(window: tk.Toplevel, width: int, height: int) -> None:
    """
    将窗口居中显示在屏幕上

    Args:
        window: 窗口对象
        width: 窗口宽度
        height: 窗口高度
    """
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()

    x = (screen_width - width) // 2
    y = (screen_height - height) // 2

    window.geometry(f"+{x}+{y}")


def create_label_button_frame(
    parent: tk.Widget,
    label_text: str,
    on_confirm: Callable[[], None],
    on_cancel: Callable[[], None],
    confirm_text: str = "确定",
    cancel_text: str = "取消"
) -> ttk.Frame:
    """
    创建标准按钮区域

    Args:
        parent: 父容器
        label_text: 说明文本
        on_confirm: 确定按钮回调
        on_cancel: 取消按钮回调
        confirm_text: 确定按钮文本
        cancel_text: 取消按钮文本

    Returns:
        按钮容器 Frame
    """
    frame = ttk.Frame(parent)
    frame.pack(pady=10)

    ttk.Button(frame, text=confirm_text, command=on_confirm, width=10).pack(side="left", padx=5)
    ttk.Button(frame, text=cancel_text, command=on_cancel, width=10).pack(side="left", padx=5)

    return frame


def create_scrolled_text(
    parent: tk.Widget,
    height: int = 5,
    font: tuple = (DEFAULT_FONT_FAMILY, 10)
) -> tk.Text:
    """
    创建带滚动条的文本框

    Args:
        parent: 父容器
        height: 文本框高度（行数）
        font: 字体设置

    Returns:
        Text 控件对象
    """
    # 创建 Text 控件
    text_widget = tk.Text(parent, height=height, font=font, wrap="word")

    # 添加滚动条
    scrollbar = ttk.Scrollbar(parent, command=text_widget.yview)
    text_widget.configure(yscrollcommand=scrollbar.set)

    return text_widget


def pack_scrolled_text(
    text_widget: tk.Text,
    scrollbar: ttk.Scrollbar,
    label_text: Optional[str] = None,
    parent: tk.Widget = None,
    padx: int = 10,
    pady_top: int = 10,
    pady_bottom: int = 5
) -> None:
    """
    布局带滚动条的文本框

    Args:
        text_widget: Text 控件
        scrollbar: 滚动条
        label_text: 可选的标签文本
        parent: 父容器（用于添加标签）
        padx: 水平边距
        pady_top: 顶部边距
        pady_bottom: 底部边距
    """
    # 添加标签（如果提供）
    if label_text and parent:
        ttk.Label(parent, text=label_text).pack(anchor="w", padx=padx, pady=(pady_top, 0))

    # 布局文本框和滚动条
    text_widget.pack(fill="both", expand=True, padx=padx, pady=(0 if label_text else pady_top, pady_bottom))
    scrollbar.pack(side="right", fill="y")


class DialogResult:
    """对话框结果封装"""

    def __init__(self, confirmed: bool, **data):
        self.confirmed = confirmed  # 用户是否点击了确定
        self.data = data             # 对话框返回的数据

    def __bool__(self) -> bool:
        """是否确认"""
        return self.confirmed

    def get(self, key: str, default=None):
        """获取数据"""
        return self.data.get(key, default)


def wait_window(dialog: tk.Toplevel) -> None:
    """
    等待窗口关闭（模态对话框标准用法）

    Args:
        dialog: 对话框窗口
    """
    dialog.wait_window()
