"""
Окружность по трём точкам.
"""

from __future__ import annotations

from typing import Tuple, cast

import axipy
from PySide2.QtCore import QPoint, Qt
from PySide2.QtGui import QPainter, QPen

from ..circle_utils import (
    CircleMapTool,
    center_and_radius_of_circle,
    ensure_util_geom_visual,
    insert_feature,
)


class CircleByPoints(CircleMapTool):

    def __init__(self, plugin: axipy.Plugin, title: str) -> None:
        super().__init__(plugin, title)

    def prepare_to_draw(self, painter: QPainter, points: list[QPoint]) -> None:
        draw_qt_ellipse(painter, points)

    def prepare_to_insert(self) -> None:
        try:
            points = self.points
            points = ensure_util_geom_visual(self.view, points)
            points = cast(Tuple[axipy.Pnt, axipy.Pnt, axipy.Pnt], points)
            result = center_and_radius_of_circle(points)
            if result is None:
                raise Exception("None")
            center, radius = result
            self.insert_ellipse(center, radius)
        except Exception:
            axipy.Notifications.push(
                self.title,
                self.plugin.tr(
                    "Не удалось построить окружность по 3-м точкам. Попробуйте ещё раз, изменив координаты."
                ),
                axipy.Notifications.Critical,
            )
        finally:
            self.clear_and_redraw()

    def insert_ellipse(self, c: axipy.Pnt, r: float) -> None:
        rect = axipy.Rect(c.x - r, c.y - r, c.x + r, c.y + r)
        rect = ensure_util_geom_visual(self.view, rect, inverse=True)
        ellipse = axipy.Ellipse(rect=rect, cs=self.view.coordsystem)
        ellipse_style = axipy.Style.from_mapinfo("Pen (1, 2, 0) Brush (1, 16777215, 16777215)")
        f = axipy.Feature(geometry=ellipse, style=ellipse_style)
        insert_feature(f)
        axipy.Notifications.push(self.title, self.plugin.tr("Окружность успешно создана."), axipy.Notifications.Success)


def draw_qt_ellipse(painter: QPainter, points: list[QPoint]) -> None:
    points = cast(Tuple[QPoint, QPoint, QPoint], points)
    result = center_and_radius_of_circle(points)
    if result is None:
        return None
    center, radius = result
    if radius == 0:
        painter.drawLine(*points[::2])
        return None

    # Запомнить старый стиль
    pen = painter.pen()
    old_pen = QPen(pen)
    # Задать новый стиль
    pen.setStyle(Qt.DashLine)
    painter.setPen(pen)
    # Нарисовать
    painter.drawEllipse(center.to_qt(), radius, radius)
    # Возвратить старый стиль
    painter.setPen(old_pen)
