import logging
import warnings
from typing import List
from typing import Optional
from typing import Sequence
from typing import Union

from . import defaults

logger = logging.getLogger(__name__)


def get_detector_names(
    detectors: Optional[Sequence[Union[int, str]]] = None,
    detector_numbers: Optional[Sequence[int]] = None,
    detector_names: Optional[Sequence[str]] = None,
    instrument_name: Optional[str] = None,
) -> List[str]:
    # Check mutually exclusive arguments
    provided = [
        detectors is not None,
        detector_numbers is not None,
        detector_names is not None,
    ]
    if sum(provided) > 1:
        raise ValueError(
            "Arguments 'detectors', 'detector_numbers', and 'detector_names' are mutually exclusive."
        )

    # Handle deprecated arguments
    if detector_numbers is not None:
        msg = "'detector_numbers' is deprecated; use 'detectors' instead."
        warnings.warn(msg, DeprecationWarning, stacklevel=2)
        logger.warning(msg)
        detectors = detector_numbers

    if detector_names is not None:
        msg = "'detector_names' is deprecated; use 'detectors' instead."
        warnings.warn(msg, DeprecationWarning, stacklevel=2)
        logger.warning(msg)
        detectors = detector_names

    name_format = defaults.MCA_NAME_FORMAT.get(instrument_name)
    names: List[str] = []
    for det in detectors:
        if isinstance(det, int):
            if not name_format:
                raise ValueError(
                    f"No MCA name format is known for instrument {instrument_name!r}"
                )
            names.append(name_format.format(det))
        elif isinstance(det, str):
            names.append(det)
        else:
            raise TypeError(f"Detector must be int or str, got {type(det)}")

    return names
