import logging
from collections import deque
from typing import Any, Collection

from where_fi.application import CSIApplication

from ..collection import ingest
from ..config import config

logger = logging.getLogger(__name__)

AntennaIdentifier = tuple[ingest.Host, int]
order: list[AntennaIdentifier] = []
prev_unplugged: set[AntennaIdentifier] = set()
long_antenna_average: dict[AntennaIdentifier, deque[int]] = {
    (host, 0): deque(maxlen=15 * config.collection_sample_rate)
    for host in config.receive_hosts
} | {
    (host, 1): deque(maxlen=15 * config.collection_sample_rate)
    for host in config.receive_hosts
}
short_antenna_average: dict[AntennaIdentifier, deque[int]] = {
    (host, 0): deque(maxlen=2 * config.collection_sample_rate)
    for host in config.receive_hosts
} | {
    (host, 1): deque(maxlen=2 * config.collection_sample_rate)
    for host in config.receive_hosts
}

RSSI_THRESHOLD = 10


def average(data: Collection[Any]) -> float:
    return sum(data) / len(data)


app = CSIApplication(ingest.RealtimeCSIProducer())


@app.on_pre_merge
def callback(antenna_data: dict[ingest.Host, ingest.CSI]) -> None:
    global prev_unplugged
    global antenna_average
    global order
    unplugged: set[tuple[ingest.Host, int]] = set()
    logger.debug(
        "Antenna RSSI: "
        + str(
            {
                host: (csi.header.rssi1, csi.header.rssi2)
                for host, csi in antenna_data.items()
            }
        )
    )
    for host, csi in antenna_data.items():
        long_antenna_average[(host, 0)].append(csi.header.rssi1)
        long_antenna_average[(host, 1)].append(csi.header.rssi2)
        short_antenna_average[(host, 0)].append(csi.header.rssi1)
        short_antenna_average[(host, 1)].append(csi.header.rssi2)

        for antenna in range(2):
            if (
                average(short_antenna_average[(host, antenna)])
                > average(long_antenna_average[(host, antenna)]) + RSSI_THRESHOLD
            ):
                unplugged.add((host, antenna))

    if prev_unplugged != unplugged:
        if len(prev_unplugged) > len(unplugged):
            logger.info(f"Antenna plugged in: {prev_unplugged - unplugged}")
        else:
            logger.info(f"Antenna unplugged: {unplugged - prev_unplugged}")
            diff = list(unplugged - prev_unplugged)
            if len(diff) == 1 and diff[0] not in order:
                host, antenna = diff.pop()
                order.append((host, antenna))
                logger.info(f"Current order: {order}")
    prev_unplugged = unplugged


def main() -> None:
    app.start()
