from __future__ import annotations

from dataclasses import dataclass
from typing import Any


FORMATTER_TARGETS = ("auto", "single", "softcore", "hardcore")
PAIR_SIDE_TARGETS = ("softcore", "hardcore")
DEFAULT_FORMATTER_TARGET = "auto"
DEFAULT_PAIR_SELECTED_SIDE = "softcore"

_TARGET_ALIASES = {
    "soft": "softcore",
    "soft_core": "softcore",
    "hard": "hardcore",
    "hard_core": "hardcore",
}


@dataclass(frozen=True)
class PairTargetPolicy:
    target: str
    pair_target: str
    selected_side: str
    include_softcore: bool
    include_hardcore: bool


def target_choices() -> list[str]:
    return list(FORMATTER_TARGETS)


def normalize_target(value: Any) -> str:
    target = str(value or "").strip().lower().replace("-", "_").replace(" ", "_")
    target = _TARGET_ALIASES.get(target, target)
    return target if target in FORMATTER_TARGETS else DEFAULT_FORMATTER_TARGET


def pair_target(value: Any) -> str:
    target = normalize_target(value)
    return target if target in PAIR_SIDE_TARGETS else DEFAULT_FORMATTER_TARGET


def pair_selected_side(value: Any, default: str = DEFAULT_PAIR_SELECTED_SIDE) -> str:
    side = pair_target(value)
    if side in PAIR_SIDE_TARGETS:
        return side
    return default if default in PAIR_SIDE_TARGETS else DEFAULT_PAIR_SELECTED_SIDE


def pair_policy(value: Any, *, selected_default: str = DEFAULT_PAIR_SELECTED_SIDE) -> PairTargetPolicy:
    target = normalize_target(value)
    side_target = pair_target(target)
    selected_side = pair_selected_side(side_target, selected_default)
    return PairTargetPolicy(
        target=target,
        pair_target=side_target,
        selected_side=selected_side,
        include_softcore=side_target in ("auto", "softcore"),
        include_hardcore=side_target in ("auto", "hardcore"),
    )
