# -*- coding: utf-8 -*-
# gui/components/model_view/contour/contour_preview_component_part2.py

# -*- coding: utf-8 -*-
# gui/components/model_view/_mv_grid_preview_core.py
# Основное превью/выделение: куб предпросмотра, высота/размеры, якорь, завершение/отмена.
from __future__ import annotations
from typing import Optional, Tuple, TYPE_CHECKING
from PySide6.QtGui import QColor

from error_logger import log_exception

if TYPE_CHECKING:  # pragma: no cover
    from gui.components.model_view_widget import ModelViewWidget

try:
    import pyvista as pv
except ImportError:  # pragma: no cover
    pv = None

class ContourPreviewComponentPart2:
    def update_height_from_mouse(self: "ModelViewWidget", mouse_y_delta: float):
        """Изменить высоту объёма перетаскиванием мыши."""
        if not self._selected_cells:
            return
        z_step = max(1.0, float(getattr(self, "_current_zone_z_size", self._current_zone_size)))
        steps = int(mouse_y_delta / 5)
        new_height = max(0, self._selected_height + steps * z_step)
        max_height = max(0.0, self._get_max_height_for_start_z() - z_step)
        if new_height > max_height:
            new_height = max_height
        if new_height != self._selected_height:
            self._selected_height = new_height
            self._update_selection_visualization()

    def _resolve_selection_anchor(
        self: "ModelViewWidget",
    ) -> Optional[Tuple[float, float]]:
        if not self._selected_cells or not self._grid_cells:
            return None
        cells = [self._grid_cells[cid] for cid in self._selected_cells if cid in self._grid_cells]
        if not cells:
            return None
        return (min(c[0] for c in cells), min(c[2] for c in cells))

    def cancel_zone_selection(self: "ModelViewWidget") -> None:
        """Остановить режим разметки и очистить временные визуалы.

        Разметочная сетка НЕ уничтожается — она скрывается и сохраняется
        для повторного использования (``_grid_ready`` остаётся True).
        Для полного удаления сетки используйте ``clear_grid()``.
        """
        self._zone_selection_mode = False
        self._selected_cells = set()
        self._selected_height = 0
        self._selection_anchor = None
        self._selection_start_cell = None
        self._volume_locked_from_contour = False
        self._contour_points = []
        self._final_contour_points = []
        self._contour_zone_mode = None
        self._contour_zone_id = None
        self._contour_ignore_zone_id = None
        self._grid_plane_z_override = None
        self.stop_contour_definition()
        self._cleanup_overlay_selection()
        self._clear_surface_grid()

        # Скрываем акторы сетки вместо удаления — для переиспользования
        self._hide_grid_actors()

        try:
            if self._preview_zone is not None:
                self._plotter.remove_actor(self._preview_zone)
                self._preview_zone = None
        except Exception as e:
            log_exception(__name__, "cancel_zone_selection", e)

        if getattr(self, "_dim_enabled", False):
            try:
                self.disable_dimension_lines()
            except Exception as e:
                log_exception(__name__, "cancel_zone_selection", e)

        try:
            self._plotter.update()
        except Exception as e:
            log_exception(__name__, "cancel_zone_selection", e)
        self.grid_volume_changed.emit(0.0, 0.0, 0.0)

    def finish_zone_selection(
        self: "ModelViewWidget",
    ) -> Optional[Tuple[float, float, float, float, float, float]]:
        """Завершить выбор зоны: вернуть (mn_x, mx_x, mn_y, mx_y, center_z, height) и сбросить состояние."""
        if not self._selected_cells or not self._grid_cells:
            self.cancel_zone_selection()
            return None

        cells = [self._grid_cells[cid] for cid in self._selected_cells]
        mn_x = min(c[0] for c in cells)
        mx_x = max(c[1] for c in cells)
        mn_y = min(c[2] for c in cells)
        mx_y = max(c[3] for c in cells)
        base_z = float(getattr(self, "_last_volume_start_height", self._get_grid_plane_z(self._grid_origin)))
        z_step = max(1.0, float(getattr(self, "_current_zone_z_size", self._current_zone_size)))
        full_height = max(z_step, z_step + float(self._selected_height))
        full_height = min(full_height, self._get_max_height_for_start_z(base_z))
        center_z = base_z + full_height / 2

        self.cancel_zone_selection()
        return (mn_x, mx_x, mn_y, mx_y, center_z, full_height)
