from __future__ import annotations

import os
from typing import TYPE_CHECKING

from OpenGL.GL import glDeleteTextures

from Imervue.gpu_image_view.images.load_thumbnail_worker import LoadThumbnailWorker

if TYPE_CHECKING:
    from Imervue.gpu_image_view.gpu_image_view import GPUImageView


def delete_current_image(main_gui: GPUImageView):
    images = main_gui.model.images

    if not images or main_gui.current_index >= len(images):
        return

    deleted_index = main_gui.current_index
    path_to_delete = images[deleted_index]

    # ===== 從 model 刪除 =====
    images.pop(deleted_index)

    # ===== 存入 undo stack（統一格式）=====
    main_gui.undo_stack.append({
        "mode": "delete",
        "deleted_paths": [path_to_delete],
        "indices": [deleted_index],
    })

    # ===== 清 GPU texture =====
    tex = main_gui.tile_textures.pop(path_to_delete, None)
    if tex is not None:
        glDeleteTextures([tex])

    # ===== 更新 current_index =====
    if images:
        main_gui.current_index = min(deleted_index, len(images) - 1)
        main_gui.load_deep_zoom_image(images[main_gui.current_index])
    else:
        main_gui.deep_zoom = None
        main_gui.current_index = 0
        main_gui.tile_grid_mode = True

    main_gui.update()


def delete_selected_tiles(main_gui):
    paths = list(main_gui.selected_tiles)
    if not paths:
        return

    images = main_gui.model.images

    deleted_paths = []
    deleted_indices = []

    for path in paths:
        if path in images:
            idx = images.index(path)
            images.remove(path)
            deleted_paths.append(path)
            deleted_indices.append(idx)

    main_gui.undo_stack.append({
        "mode": "delete",
        "deleted_paths": deleted_paths,
        "indices": deleted_indices,
    })

    # GPU
    for path in deleted_paths:
        tex = main_gui.tile_textures.pop(path, None)
        if tex is not None:
            glDeleteTextures([tex])

    # CPU cache
    for path in deleted_paths:
        main_gui.tile_cache.pop(path, None)

    main_gui.selected_tiles.clear()
    main_gui.tile_selection_mode = False
    main_gui.tile_rects.clear()

    main_gui.update()

def undo_delete(main_gui: GPUImageView):
    if not main_gui.undo_stack:
        return

    action = main_gui.undo_stack.pop()

    if action.get("mode") != "delete":
        return

    paths = action["deleted_paths"]
    indices = action["indices"]

    # ===== 依 index 排序插回 =====
    for path, idx in sorted(zip(paths, indices), key=lambda x: x[1]):
        main_gui.model.images.insert(idx, path)

        # ===== 重新載入 thumbnail（tile grid 用）=====
        worker = LoadThumbnailWorker(path, main_gui.thumbnail_size)
        worker.signals.finished.connect(main_gui.add_thumbnail)
        main_gui.thread_pool.start(worker)

    # ===== 如果在 deep zoom 模式，重新載入當前圖 =====
    if main_gui.deep_zoom and main_gui.model.images:
        current_path = main_gui.model.images[main_gui.current_index]
        main_gui.load_deep_zoom_image(current_path)

    main_gui.update()


def clear_thumbnail_cache(main_gui: GPUImageView):
    for tex in main_gui.tile_textures.values():
        glDeleteTextures([tex])
    main_gui.tile_textures.clear()


def commit_pending_deletions(main_gui: GPUImageView):
    for action in main_gui.undo_stack:
        for path in action.get("deleted_paths", []):
            try:
                if os.path.exists(path):
                    os.remove(path)
                    print(f"Permanent delete: {path}")
            except Exception as e:
                print(f"Failed to permanently delete {path}: {e}")

    main_gui.undo_stack.clear()
