import tkinter as tk
from unittest.mock import MagicMock, patch

import pytest

from tarot.tarot_api import Tarot
from tarot.ui import CubeDisplay


def test_zoom_limits():
    # Mock Tk root
    class MockRoot:
        def __init__(self):
            self.bindings = {}
            self.images = []

        def bind(self, key, callback):
            pass

        def title(self, _):
            pass

        def update_idletasks(self):
            pass

        def winfo_reqwidth(self):
            return 800

        def winfo_reqheight(self):
            return 600

        def winfo_screenwidth(self):
            return 1920

        def winfo_screenheight(self):
            return 1080

        def geometry(self, _):
            pass

        def mainloop(self):
            pass

        def focus_force(self):
            pass

    # Mock Frame
    class MockFrame:
        def __init__(self, master=None, **kwargs):
            self.children = []
            self.master = master

        def pack(self, **kwargs):
            pass

        def place(self, **kwargs):
            pass

        def grid(self, **kwargs):
            pass

        def grid_propagate(self, flag):
            pass

        def winfo_children(self):
            return self.children

        def destroy(self):
            pass

        def update_idletasks(self):
            pass

        def winfo_reqwidth(self):
            return 100

        def winfo_reqheight(self):
            return 100

        def bind(self, event, callback):
            pass

    # Mock Canvas
    class MockCanvas:
        def __init__(self, master=None, **kwargs):
            self.master = master

        def pack(self, **kwargs):
            pass

        def bind(self, event, callback):
            pass

        def create_window(self, coords, **kwargs):
            return 1

        def config(self, **kwargs):
            pass

        def bbox(self, tag):
            return (0, 0, 100, 100)

        def winfo_width(self):
            return 800

        def winfo_height(self):
            return 600

        def coords(self, item, x, y):
            pass

        def scan_mark(self, x, y):
            pass

        def scan_dragto(self, x, y, gain=1):
            pass

        def canvasx(self, x):
            return x

        def canvasy(self, y):
            return y

        def xview_moveto(self, fraction):
            pass

        def yview_moveto(self, fraction):
            pass

    # Monkey patch tk
    original_tk = tk.Tk
    original_frame = tk.ttk.Frame
    original_canvas = tk.Canvas
    original_label = tk.ttk.Label
    original_button = tk.ttk.Button

    # Mock Label and Button
    class MockWidget:
        def __init__(self, master=None, **kwargs):
            self.master = master

        def pack(self, **kwargs):
            pass

        def place(self, **kwargs):
            pass

        def grid(self, **kwargs):
            pass

        def grid_propagate(self, flag):
            pass

    try:
        tk.Tk = MockRoot
        tk.ttk.Frame = MockFrame
        tk.Canvas = MockCanvas
        tk.ttk.Label = MockWidget
        tk.ttk.Button = MockWidget

        # Mock Image to avoid memory issues
        with patch("PIL.Image.open") as mock_open:
            mock_img = MagicMock()
            mock_img.size = (100, 100)
            mock_img.resize.return_value = mock_img
            mock_open.return_value = mock_img

            with patch("PIL.ImageTk.PhotoImage") as mock_photo:

                cube = Tarot.cube
                display = CubeDisplay(cube)
                display.root = MockRoot()
                display.canvas = MockCanvas()
                display.content_frame = MockFrame()
                display.canvas_window = 1  # Mock window ID

                # Test initial zoom
                assert display.zoom_level == 1.0

                # Test zoom in
                display._zoom(1.22)
                assert display.zoom_level == 1.22

                # Test max limit (should be 50.0)
                # Zoom way in
                for _ in range(100):
                    display._zoom(1.22)

                assert display.zoom_level == 50.0

                # Test min limit (should be 0.1)
                # Zoom way out
                for _ in range(200):
                    display._zoom(0.5)

                assert display.zoom_level == 0.1

    finally:
        tk.Tk = original_tk
        tk.ttk.Frame = original_frame
        tk.Canvas = original_canvas
        tk.ttk.Label = original_label
        tk.ttk.Button = original_button
