"""Shared settings persistence helpers.

This service centralises storage and validation for application settings that are
shared between setup and runtime configuration workflows.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import structlog

from app.repositories import settings_repo

if TYPE_CHECKING:  # pragma: no cover
    import aiosqlite

log: structlog.stdlib.BoundLogger = structlog.get_logger()

_KEY_MAP_COLOR_THRESHOLD_HIGH = "map_color_threshold_high"
_KEY_MAP_COLOR_THRESHOLD_MEDIUM = "map_color_threshold_medium"
_KEY_MAP_COLOR_THRESHOLD_LOW = "map_color_threshold_low"

_DEFAULT_MAP_COLOR_THRESHOLD_HIGH = 100
_DEFAULT_MAP_COLOR_THRESHOLD_MEDIUM = 50
_DEFAULT_MAP_COLOR_THRESHOLD_LOW = 20


async def get_map_color_thresholds(
    db: aiosqlite.Connection,
) -> tuple[int, int, int]:
    """Return map color thresholds from stored settings.

    Args:
        db: Active aiosqlite connection.

    Returns:
        A tuple of ``(high, medium, low)`` thresholds.
    """
    high = await settings_repo.get_setting(db, _KEY_MAP_COLOR_THRESHOLD_HIGH)
    medium = await settings_repo.get_setting(db, _KEY_MAP_COLOR_THRESHOLD_MEDIUM)
    low = await settings_repo.get_setting(db, _KEY_MAP_COLOR_THRESHOLD_LOW)

    return (
        int(high) if high else _DEFAULT_MAP_COLOR_THRESHOLD_HIGH,
        int(medium) if medium else _DEFAULT_MAP_COLOR_THRESHOLD_MEDIUM,
        int(low) if low else _DEFAULT_MAP_COLOR_THRESHOLD_LOW,
    )


async def set_map_color_thresholds(
    db: aiosqlite.Connection,
    *,
    threshold_high: int,
    threshold_medium: int,
    threshold_low: int,
) -> None:
    """Persist validated map color thresholds.

    Args:
        db: Active aiosqlite connection.
        threshold_high: High threshold value.
        threshold_medium: Medium threshold value.
        threshold_low: Low threshold value.

    Raises:
        ValueError: If thresholds are non-positive or misordered.
    """
    if threshold_high <= 0 or threshold_medium <= 0 or threshold_low <= 0:
        raise ValueError("All thresholds must be positive integers.")
    if not (threshold_high > threshold_medium > threshold_low):
        raise ValueError("Thresholds must satisfy: high > medium > low.")

    await settings_repo.set_setting(
        db, _KEY_MAP_COLOR_THRESHOLD_HIGH, str(threshold_high)
    )
    await settings_repo.set_setting(
        db, _KEY_MAP_COLOR_THRESHOLD_MEDIUM, str(threshold_medium)
    )
    await settings_repo.set_setting(
        db, _KEY_MAP_COLOR_THRESHOLD_LOW, str(threshold_low)
    )

    log.info(
        "map_color_thresholds_persisted",
        high=threshold_high,
        medium=threshold_medium,
        low=threshold_low,
    )
