from datetime import datetime
from pathlib import Path
from .util import sleep, get_addr, digital_read, GDO0_PIN, GDO2_PIN, debug, delay
import time
from .common import strobe, read_register

SIDLE = get_addr('SIDLE')
SFRX = get_addr('SFRX')
SRX = get_addr('SRX')
RXFIFO = get_addr('RXFIFO')
RSSI = get_addr('RSSI')

def print_packet(spi, packet_length):
    for i in range(packet_length):
        print(f", byte: {0}: 0x{1}", i, read_register(spi, RXFIFO))

# Save packet to a timestamped binary file
def save_packet(packet: list):
    # Create directory to store packets if it doesn't exist
    packet_dir = Path("saved_packets")
    packet_dir.mkdir(parents=True, exist_ok=True)

    # Create timestamped filename
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = packet_dir / f"packet_{timestamp}.bin"

    # Save packet as binary data
    with open(filename, "wb") as f:
        f.write(bytearray(packet))

    print(f"Packet saved to {filename}")


def get_rssi_from_pkt(packet):
    if len(packet) < 2:
        raise ValueError("Packet too short to contain RSSI and status bytes.")
    rssi_raw = packet[-2]  # Second-to-last byte is RSSI
    return rssi_raw


def get_rssi_from_reg(spi):
    return read_register(spi, RSSI)

def get_signal_strength_rssi_raw(rssi_raw):
    if rssi_raw >= 128:
        rssi_dec = rssi_raw - 256
    else:
        rssi_dec = rssi_raw
    return rssi_dec / 2.0 - 74 # According to CC2500 datasheet

def flush_rx(spi):
    # Make sure that the radio is in IDLE state before flushing the FIFO
    # (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point)
    delay(10)
    strobe(spi, SIDLE)
    delay(10)
    # Flush RX FIFO
    strobe(spi, SFRX)
    delay(10)

def rx_data_rf(spi):
    strobe(spi, SRX)
    gdo2_state = False
    count = 0
    strength = 0
    while(gdo2_state == False):
        gdo2_state = digital_read(GDO2_PIN)
        delay(1)
        count = count+1
        if count > 1000:
            flush_rx(spi)
            # print("ERR NO DATA")
            return
    while(gdo2_state == True):
        gdo2_state = digital_read(GDO2_PIN)
        delay(100)
    packet_length: int = read_register(spi, RXFIFO)
    packet: list = [read_register(spi, RXFIFO) for _ in range(packet_length)]
    rssi_raw = get_rssi_from_pkt(packet)
    strength = get_signal_strength_rssi_raw(rssi_raw)
    print("Length: {0} bytes\t Signal: {1} dBm".format(packet_length, strength) )
    save_packet(packet)
    # Make sure that the radio is in IDLE state before flushing the FIFO
    # (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point)
    strobe(spi, SIDLE)
    # Flush RX FIFO
    strobe(spi, SFRX)
