#!/usr/bin/env python3

from typing import Optional


LTE_EARFCN_BAND_RANGES = [
    (1, 0, 599),
    (2, 600, 1199),
    (3, 1200, 1949),
    (4, 1950, 2399),
    (5, 2400, 2649),
    (7, 2750, 3449),
    (8, 3450, 3799),
    (12, 5010, 5179),
    (13, 5180, 5279),
    (14, 5280, 5379),
    (17, 5730, 5849),
    (18, 5850, 5999),
    (19, 6000, 6149),
    (20, 6150, 6449),
    (21, 6450, 6599),
    (24, 7700, 8039),
    (25, 8040, 8689),
    (26, 8690, 9039),
    (28, 9210, 9659),
    (29, 9660, 9769),
    (30, 9770, 9869),
    (32, 9920, 10359),
    (34, 36200, 36349),
    (38, 37750, 38249),
    (39, 38250, 38649),
    (40, 38650, 39649),
    (41, 39650, 41589),
    (42, 41590, 43589),
    (43, 43590, 45589),
    (48, 55240, 56739),
    (66, 66436, 67335),
    (71, 68586, 68935),
]

NR_ARFCN_BAND_RANGES = [
    (1, 422000, 434000),
    (3, 361000, 376000),
    (5, 173800, 178800),
    (7, 524000, 538000),
    (8, 185000, 192000),
    (20, 158200, 164200),
    (28, 151600, 160600),
    (38, 514000, 524000),
    (40, 460000, 480000),
    (41, 499200, 538000),
    (66, 422000, 440000),
    (71, 123400, 130400),
    (77, 620000, 680000),
    (78, 620000, 653333),
    (79, 693333, 733333),
    (257, 2054166, 2104165),
    (258, 2016667, 2070832),
    (260, 2229166, 2279165),
    (261, 2070833, 2084999),
]


def _parse_arfcn_value(freq_dl: object) -> Optional[int]:
    if freq_dl is None:
        return None
    text = str(freq_dl).strip()
    if not text:
        return None
    try:
        return int(float(text))
    except (TypeError, ValueError):
        return None


def derive_band_from_arfcn(rat: object, freq_dl: object) -> object:
    rat_text = str(rat).strip()
    arfcn = _parse_arfcn_value(freq_dl)
    if arfcn is None:
        return ""
    if rat_text == "NR":
        matches = [
            (band, high - low, low)
            for band, low, high in NR_ARFCN_BAND_RANGES
            if low <= arfcn <= high
        ]
        if matches:
            return sorted(matches, key=lambda item: (item[1], item[2], item[0]))[0][0]
    if rat_text == "LTE":
        for band, low, high in LTE_EARFCN_BAND_RANGES:
            if low <= arfcn <= high:
                return band
    return ""
