import threading
import time
from datetime import datetime

class TransmissionController:
    """Handles transmission cycle logic and state management"""
    
    def __init__(self, gpio_controller, data_logger, status_callback=None):
        self.gpio_controller = gpio_controller
        self.data_logger = data_logger
        self.status_callback = status_callback or (lambda msg: print(f"[TX] {msg}"))
        
        # Transmission state
        self.cycle_state = 'idle'  # 'idle', 'transmitting', 'pausing'
        self.cycle_timer = None
        
        # Timing settings
        self.transmit_time = 60  # seconds
        self.pause_time = 30     # seconds
        
        # Current frequency
        self.current_frequency = 1.0
        
        # GUI callbacks
        self.gui_callbacks = {}
        
        # Threading lock
        self.state_lock = threading.Lock()
    
    def set_timing_parameters(self, transmit_time, pause_time):
        """Set transmit and pause times"""
        with self.state_lock:
            self.transmit_time = transmit_time
            self.pause_time = pause_time
        self.status_callback(f"Timing updated: {transmit_time}s TX, {pause_time}s pause")
    
    def set_frequency(self, frequency):
        """Set transmission frequency"""
        with self.state_lock:
            self.current_frequency = frequency
    
    def register_gui_callbacks(self, callbacks):
        """Register GUI update callbacks"""
        self.gui_callbacks = callbacks
    
    def start_transmission_cycle(self):
        """Start the transmit/pause cycle"""
        with self.state_lock:
            if self.cycle_state != 'idle':
                self.status_callback("Transmission cycle already active")
                return False
                
            self.status_callback(f"Starting transmission cycle: {self.transmit_time}s ON, {self.pause_time}s OFF")
            self.cycle_state = 'transmitting'
        
        self._start_gpio_transmission()
        
        # Log transmission start
        if self.data_logger.is_logging_active():
            self.data_logger.log_transmission_start(self.current_frequency)
        
        # Schedule pause after transmit time
        self.cycle_timer = threading.Timer(self.transmit_time, self._start_pause_cycle)
        self.cycle_timer.start()
        return True
    
    def stop_transmission_cycle(self):
        """Stop the transmission cycle"""
        with self.state_lock:
            was_active = self.cycle_state != 'idle'
            self.cycle_state = 'idle'
        
        # Cancel any pending timer
        if self.cycle_timer:
            self.cycle_timer.cancel()
            self.cycle_timer = None
        
        # Stop GPIO transmission
        self._stop_gpio_transmission()
        
        # Log manual stop if it was active
        if was_active and self.data_logger.is_logging_active():
            self.data_logger.log_manual_stop()
        
        self.status_callback("Transmission cycle stopped")
        return True
    
    def get_cycle_state(self):
        """Get current cycle state"""
        with self.state_lock:
            return self.cycle_state
    
    def is_active(self):
        """Check if transmission cycle is active"""
        with self.state_lock:
            return self.cycle_state != 'idle'
    
    def _start_gpio_transmission(self):
        """Start actual GPIO transmission"""
        # Set up indicator callbacks for GUI
        indicator_callbacks = {
            'onoff': self.gui_callbacks.get('onoff_indicator'),
            'duty': self.gui_callbacks.get('duty_indicator'), 
            'polarity': self.gui_callbacks.get('polarity_indicator')
        }
        
        # Start GPIO transmission
        self.gpio_controller.start_transmission(self.current_frequency, indicator_callbacks)
        
        # Update GUI status
        if 'status_update' in self.gui_callbacks:
            self.gui_callbacks['status_update']("TRANSMITTING", "green")
    
    def _stop_gpio_transmission(self):
        """Stop GPIO transmission"""
        indicator_callbacks = {
            'onoff': self.gui_callbacks.get('onoff_indicator'),
            'duty': self.gui_callbacks.get('duty_indicator'),
            'polarity': self.gui_callbacks.get('polarity_indicator')
        }
        
        self.gpio_controller.stop_transmission(indicator_callbacks)
        
        # Update GUI status
        if 'status_update' in self.gui_callbacks:
            self.gui_callbacks['status_update']("NOT TRANSMITTING", "red")
    
    def _start_pause_cycle(self):
        """Start pause cycle"""
        with self.state_lock:
            if self.cycle_state != 'transmitting':
                return
            
            self.status_callback(f"Starting pause cycle: {self.pause_time}s")
            self.cycle_state = 'pausing'
        
        # Log pause start
        if self.data_logger.is_logging_active():
            self.data_logger.log_pause_start(self.pause_time)
        
        # Stop GPIO transmission
        self._stop_gpio_transmission()
        
        # Update GUI status for pause
        if 'status_update' in self.gui_callbacks:
            self.gui_callbacks['status_update']("PAUSED", "orange")
        
        # Schedule next transmission after pause time
        if self.pause_time > 0:
            self.cycle_timer = threading.Timer(self.pause_time, self._resume_transmission_cycle)
            self.cycle_timer.start()
        else:
            # If pause time is 0, immediately resume
            self._resume_transmission_cycle()
    
    def _resume_transmission_cycle(self):
        """Resume transmission after pause"""
        with self.state_lock:
            if self.cycle_state != 'pausing':
                return
            
            self.status_callback("Resuming transmission cycle")
            self.cycle_state = 'transmitting'
        
        # Log pause completion
        if self.data_logger.is_logging_active():
            self.data_logger.log_pause_complete()
        
        self._start_gpio_transmission()
        
        # Schedule next pause
        self.cycle_timer = threading.Timer(self.transmit_time, self._start_pause_cycle)
        self.cycle_timer.start()
    
    def cleanup(self):
        """Clean up transmission controller"""
        self.stop_transmission_cycle()
        self.status_callback("Transmission controller cleaned up")