"""
Tabela de referência da Tag Padrão #124 para o módulo Calibration.
Contida no módulo Calibration; suporta constante em código e JSON para fácil troca de tabela.
"""
import os
import json
from typing import Dict, List, Tuple, Optional

from .app_console import fc_log
# EPC da Tag Padrão aceita para calibração (gravado no módulo como base)
TAG_REFERENCE_EPC = "000000000000000588937124"

# Tabela Tag #124: Frequency (MHz) -> (Power on Tag Forward dBm, Power on Tag Reverse dBm)
# 800-1000 MHz, passo 1 MHz (201 pontos). Carregada de tag_referencia_124.json; fallback abaixo (subconjunto).
REFERENCE_FREQ_MIN = 800
REFERENCE_FREQ_MAX = 1000
REFERENCE_FREQ_STEP = 1

# Fallback mínimo se JSON não existir (pontos 800, 850, 900, 950, 1000)
REFERENCE_TABLE_TAG_124: List[Tuple[int, float, float]] = [
    (800, -8.614, -29.753),
    (850, -16.292, -26.611),
    (900, -18.045, -23.621),
    (950, -16.34, -18.755),
    (1000, -16.991, -16.008),
]


def get_reference_table() -> List[Tuple[int, float, float]]:
    """
    Retorna a tabela de referência (Tag #124).
    Tenta carregar de JSON no mesmo diretório (tag_referencia_124.json);
    se não existir, usa a constante REFERENCE_TABLE_TAG_124.
    """
    try:
        base_dir = os.path.dirname(os.path.abspath(__file__))
        json_path = os.path.join(base_dir, "tag_referencia_124.json")
        if os.path.isfile(json_path):
            with open(json_path, "r", encoding="utf-8") as f:
                data = json.load(f)
            # Esperado: {"points": [[freq, forward_dbm, reverse_dbm], ...]} ou lista de objetos
            points = data.get("points", data) if isinstance(data, dict) else data
            out = []
            for row in points:
                if isinstance(row, (list, tuple)) and len(row) >= 3:
                    out.append((int(row[0]), float(row[1]), float(row[2])))
                elif isinstance(row, dict):
                    out.append((
                        int(row.get("frequency_mhz", row.get("freq", 0))),
                        float(row.get("power_on_tag_forward_dbm", row.get("forward", 0))),
                        float(row.get("power_on_tag_reverse_dbm", row.get("reverse", 0))),
                    ))
            if out:
                return sorted(out, key=lambda x: x[0])
    except Exception as e:
        fc_log("calibration_ref", f"[Calibration] Não foi possível carregar tag_referencia_124.json: {e}")
    return list(REFERENCE_TABLE_TAG_124)


def get_reference_forward_reverse(freq_mhz: float) -> Tuple[float, float]:
    """
    Retorna (Power on Tag Forward dBm, Power on Tag Reverse dBm) para a frequência dada.
    Interpola linearmente entre os pontos da tabela.
    """
    table = get_reference_table()
    if not table:
        return (0.0, 0.0)
    freqs = [p[0] for p in table]
    forwards = [p[1] for p in table]
    reverses = [p[2] for p in table]
    if freq_mhz <= freqs[0]:
        return (forwards[0], reverses[0])
    if freq_mhz >= freqs[-1]:
        return (forwards[-1], reverses[-1])
    for i in range(len(freqs) - 1):
        if freqs[i] <= freq_mhz <= freqs[i + 1]:
            t = (freq_mhz - freqs[i]) / (freqs[i + 1] - freqs[i]) if freqs[i + 1] != freqs[i] else 0
            fwd = forwards[i] + t * (forwards[i + 1] - forwards[i])
            rev = reverses[i] + t * (reverses[i + 1] - reverses[i])
            return (fwd, rev)
    return (forwards[-1], reverses[-1])
