"""
CLI Shell - Interactive command-line interface
Refactored to use package modules
"""

import os
import sys
import signal
import subprocess
import logging
from datetime import datetime

from .rtc import RTCManager
from .watchdog import WatchDogManager

logger = logging.getLogger(__name__)

class RTCShell:
    """Interactive CLI shell for RTC and WatchDog management"""
    
    def __init__(self):
        self.rtc = None
        self.watchdog = None
        self.running = True
        self.mock_mode = os.environ.get('RTC_MOCK', 'false').lower() == 'true'
        
        # Setup signal handlers
        signal.signal(signal.SIGINT, self.signal_handler)
        signal.signal(signal.SIGTERM, self.signal_handler)
        
        # Initialize managers
        self._init_managers()
        
        self._show_banner()
    
    def _init_managers(self):
        """Initialize RTC and WatchDog managers"""
        rtc_addr = int(os.environ.get('RTC_I2C_ADDRESS', '0x68'), 16)
        wd_addr = int(os.environ.get('WATCHDOG_I2C_ADDRESS', '0x67'), 16)
        wd_gpio = int(os.environ.get('WATCHDOG_GPIO_PIN', '4'))
        
        self.rtc = RTCManager(
            i2c_address=rtc_addr,
            mock=self.mock_mode
        )
        
        self.watchdog = WatchDogManager(
            i2c_address=wd_addr,
            gpio_pin=wd_gpio,
            mock=self.mock_mode
        )
    
    def _show_banner(self):
        """Display startup banner"""
        print("\n" + "="*50)
        print("  piRTC - RPi RTC & WatchDog CLI Shell")
        print("="*50)
        print(f"RTC: {'Available' if self.rtc.available else 'Unavailable'} " +
              f"(Mock: {self.rtc.mock})")
        print(f"WatchDog: {'Available' if self.watchdog.available else 'Unavailable'} " +
              f"(Mock: {self.watchdog.mock})")
        print("="*50)
        print("Type 'help' for commands or 'exit' to quit\n")
    
    def signal_handler(self, signum, frame):
        """Handle Ctrl+C gracefully"""
        print("\n\nShutting down...")
        self.running = False
    
    def show_help(self):
        """Show available commands"""
        help_text = """
Available Commands:
====================
RTC Commands:
  rtc-time          - Read current time from RTC
  rtc-date          - Read current date from RTC  
  rtc-temp          - Read temperature from RTC
  rtc-set <h> <m> <s> - Set time (24-hour format)
  rtc-set <y> <m> <d> - Set date
  rtc-info          - Show all RTC information
  rtc-sync-system   - Sync RTC time to system
  rtc-sync-rtc      - Sync system time to RTC

WatchDog Commands:
  wd-feed           - Feed the watchdog
  wd-version        - Get watchdog firmware version
  wd-info           - Show watchdog information
  wd-test           - Run watchdog test loop

System Commands:
  i2c-scan          - Scan I2C bus for devices
  status            - Show system status
  mock-on           - Enable mock mode
  mock-off          - Disable mock mode
  clear             - Clear screen
  help              - Show this help
  exit              - Exit shell

Examples:
  rtc-set 14 30 0   # Set time to 14:30:00
  rtc-set 2026 3 15 # Set date to March 15, 2026
  wd-feed           # Feed the watchdog
"""
        print(help_text)
    
    def scan_i2c(self):
        """Scan I2C bus for devices"""
        print("Scanning I2C bus...")
        try:
            result = subprocess.run(
                ['i2cdetect', '-y', '1'],
                capture_output=True,
                text=True
            )
            if result.returncode == 0:
                print(result.stdout)
            else:
                print("I2C scan failed. Try: sudo i2cdetect -y 1")
        except FileNotFoundError:
            print("i2cdetect not found. Install: sudo apt-get install i2c-tools")
        except Exception as e:
            print(f"Error: {e}")
    
    def show_status(self):
        """Show system status"""
        print("\n" + "="*40)
        print("SYSTEM STATUS")
        print("="*40)
        
        # RTC status
        status = self.rtc.get_status()
        print(f"\nRTC:")
        print(f"  Available: {status['available']}")
        print(f"  Mock: {status['mock']}")
        print(f"  I2C: {status['i2c_address']} (bus {status['i2c_bus']})")
        if status.get('time'):
            print(f"  Time: {status['time']}")
        if status.get('date'):
            print(f"  Date: {status['date']}")
        if status.get('temperature') is not None:
            print(f"  Temp: {status['temperature']:.1f}°C")
        
        # WatchDog status
        wd_status = self.watchdog.get_status()
        print(f"\nWatchDog:")
        print(f"  Available: {wd_status['available']}")
        print(f"  Mock: {wd_status['mock']}")
        print(f"  I2C: {wd_status['i2c_address']} (bus {wd_status['i2c_bus']})")
        print(f"  GPIO: {wd_status['gpio_pin']}")
        print(f"  Timeout: {wd_status['timeout']}s")
        if wd_status.get('version') is not None:
            print(f"  Version: {wd_status['version']}")
        
        print("\n" + "="*40 + "\n")
    
    def process_command(self, cmd: str):
        """Process user command"""
        parts = cmd.strip().split()
        if not parts:
            return
        
        command = parts[0].lower()
        
        # Help
        if command == 'help':
            self.show_help()
        
        # Exit
        elif command in ['exit', 'quit']:
            self.running = False
            print("Goodbye!")
        
        # Clear
        elif command == 'clear':
            os.system('clear')
        
        # RTC Commands
        elif command == 'rtc-time':
            time_data = self.rtc.read_time()
            if time_data:
                print(f"RTC Time: {time_data['hour']:02d}:{time_data['minute']:02d}:{time_data['second']:02d}")
                if time_data.get('mock'):
                    print("(Mock data)")
            else:
                print("Failed to read RTC time")
        
        elif command == 'rtc-date':
            date_data = self.rtc.read_date()
            if date_data:
                print(f"RTC Date: {date_data['year']}-{date_data['month']:02d}-{date_data['day']:02d}")
                if date_data.get('mock'):
                    print("(Mock data)")
            else:
                print("Failed to read RTC date")
        
        elif command == 'rtc-temp':
            temp_data = self.rtc.read_temperature()
            if temp_data:
                print(f"RTC Temperature: {temp_data['temperature']:.2f}°C")
                if temp_data.get('mock'):
                    print("(Mock data)")
            else:
                print("Failed to read temperature")
        
        elif command == 'rtc-set':
            if len(parts) == 4:
                try:
                    h, m, s = map(int, parts[1:])
                    if self.rtc.set_time(h, m, s):
                        print("Time set successfully")
                except ValueError:
                    print("Invalid format. Use: rtc-set <hour> <minute> <second>")
            elif len(parts) == 4 and len(parts[1]) == 4:
                try:
                    y, m, d = map(int, parts[1:])
                    if self.rtc.set_date(y, m, d):
                        print("Date set successfully")
                except ValueError:
                    print("Invalid format. Use: rtc-set <year> <month> <day>")
            else:
                print("Usage: rtc-set <hour> <minute> <second> OR rtc-set <year> <month> <day>")
        
        elif command == 'rtc-info':
            self.show_status()
        
        elif command == 'rtc-sync-system':
            if self.rtc.sync_to_system():
                print("System time synchronized with RTC")
            else:
                print("Failed to sync system time")
        
        elif command == 'rtc-sync-rtc':
            if self.rtc.sync_from_system():
                print("RTC synchronized with system time")
            else:
                print("Failed to sync RTC")
        
        # WatchDog Commands
        elif command == 'wd-feed':
            if self.watchdog.feed():
                print("WatchDog fed successfully")
            else:
                print("Failed to feed WatchDog")
        
        elif command == 'wd-version':
            version = self.watchdog.get_version()
            if version:
                print(f"WatchDog Version: {version['version']}")
                if version.get('mock'):
                    print("(Mock data)")
            else:
                print("Failed to get WatchDog version")
        
        elif command == 'wd-info':
            status = self.watchdog.get_status()
            print(f"\nWatchDog Information:")
            print(f"  Available: {status['available']}")
            print(f"  I2C Address: {status['i2c_address']}")
            print(f"  GPIO Pin: {status['gpio_pin']}")
            print(f"  Timeout: {status['timeout']}s")
            if status.get('version') is not None:
                print(f"  Version: {status['version']}")
            print()
        
        elif command == 'wd-test':
            print("Running WatchDog test loop (5 feeds, 2s interval)...")
            self.watchdog.test_feed_loop(count=5, interval=2.0)
        
        # System Commands
        elif command == 'i2c-scan':
            self.scan_i2c()
        
        elif command == 'status':
            self.show_status()
        
        elif command == 'mock-on':
            os.environ['RTC_MOCK'] = 'true'
            self.mock_mode = True
            self._init_managers()
            print("Mock mode enabled. Managers reinitialized.")
        
        elif command == 'mock-off':
            os.environ['RTC_MOCK'] = 'false'
            self.mock_mode = False
            self._init_managers()
            print("Mock mode disabled. Managers reinitialized.")
        
        else:
            print(f"Unknown command: {command}. Type 'help' for available commands.")
    
    def run(self):
        """Main shell loop"""
        while self.running:
            try:
                cmd = input("piRTC> ").strip()
                if cmd:
                    self.process_command(cmd)
            except EOFError:
                print("\nGoodbye!")
                break
            except KeyboardInterrupt:
                print("\nUse 'exit' to quit")
            except Exception as e:
                logger.error(f"Error: {e}")

def main():
    """CLI entry point"""
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )
    
    shell = RTCShell()
    shell.run()

if __name__ == "__main__":
    main()
