"""
senzib.integrations.profitbase.utils

Утилиты для работы с графикой/планами Profitbase.

Сейчас основной хелпер:

    color_area_on_image(image_source, coordinates, ...)

Он:
- Загружает картинку по URL (или локальному пути).
- Рисует полупрозрачный полигон по координатам.
- Либо сохраняет PNG в указанный путь, либо возвращает BytesIO с PNG-данными.
"""

from __future__ import annotations

from io import BytesIO
from pathlib import Path
from typing import Iterable, List, Mapping, Optional, Tuple, Union

import requests
from PIL import Image, ImageDraw


def _load_image_from_source(image_source: str) -> Image.Image:
    """
    Загружает изображение из URL или локального пути.

    :param image_source: либо http(s) URL, либо путь к файлу.
    :return: PIL.Image.Image
    :raises IOError: если не удалось загрузить/открыть изображение.
    """
    if image_source.startswith("http://") or image_source.startswith("https://"):
        resp = requests.get(image_source)
        resp.raise_for_status()
        return Image.open(BytesIO(resp.content))
    else:
        # считаем, что это локальный путь
        return Image.open(image_source)


def color_area_on_image(
    image_source: str,
    coordinates: Iterable[Mapping[str, float]],
    *,
    fill_rgba: Tuple[int, int, int, int] = (100, 100, 100, 150),
    outline: Optional[Union[str, Tuple[int, int, int, int]]] = "green",
    save_to: Optional[Union[str, Path]] = None,
) -> Union[BytesIO, Path]:
    """
    Закрашивает полигон (область помещения) на плане.

    :param image_source:
        Источник изображения — либо URL (http/https),
        либо путь к локальному файлу.
    :param coordinates:
        Итерация по точкам с ключами "x" и "y":
            [{"x": 10, "y": 20}, {"x": 30, "y": 40}, ...]
    :param fill_rgba:
        Цвет и прозрачность заливки в формате RGBA.
        По умолчанию — полупрозрачный серый (100,100,100,150).
    :param outline:
        Цвет обводки полигона — строка (имя цвета) или RGBA-튜пл,
        либо None, если обводка не нужна.
    :param save_to:
        Если указан (str или Path) — изображение будет сохранено в PNG
        по этому пути, и функция вернёт Path.
        Если None — вернёт BytesIO с PNG-данными.

    :return:
        - Path (если указан save_to)
        - или BytesIO (если save_to is None)

    :raises IOError:
        - при ошибках загрузки/открытия изображения
        - при ошибках сохранения файла
    """
    # 1. Загружаем изображение
    image = _load_image_from_source(image_source).convert("RGBA")

    # 2. Преобразуем координаты в список (x, y)
    coords: List[Tuple[float, float]] = [
        (float(point["x"]), float(point["y"])) for point in coordinates
    ]

    # 3. Создаём маску/оверлей
    mask = Image.new("RGBA", image.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(mask)

    # Рисуем полигон:
    # - fill_rgba — заливка
    # - outline — цвет обводки (может быть None)
    draw.polygon(coords, outline=outline, fill=fill_rgba)

    # 4. Накладываем маску на исходное изображение
    image_with_overlay = Image.alpha_composite(image, mask)

    # 5. Сохраняем или отдаём в память
    if save_to is not None:
        path = Path(save_to)
        path.parent.mkdir(parents=True, exist_ok=True)
        image_with_overlay.save(path, format="PNG")
        return path

    buffer = BytesIO()
    image_with_overlay.save(buffer, format="PNG")
    buffer.seek(0)
    return buffer


__all__ = [
    "color_area_on_image",
]


"""
ПРИМЕР ИСПОЛЬЗОВАНИЯ В ПРИЛОЖЕНИИ

from senzib.integrations.profitbase.client import ProfitbaseClient
from senzib.integrations.profitbase.utils import color_area_on_image

client = ProfitbaseClient(account_number="pb15930", access_token="...")

coords_info = client.get_floor_coordinates(house_id=123, property_id=456)
if coords_info:
    image_source = coords_info["image_source"]
    coordinates = coords_info["coordinates"]

    # Вариант 1: получить BytesIO (например, отдать сразу в HTTP-ответе)
    buffer = color_area_on_image(image_source, coordinates)

    # Вариант 2: сохранить в файл (приложение само решает путь)
    output_path = color_area_on_image(
        image_source,
        coordinates,
        save_to="/var/app/data/floors/floor_plan_456.png",
    )

"""