"""
RTC Manager - DS3231 Real-Time Clock Interface
"""

import os
import sys
import logging
from datetime import datetime
from typing import Optional, Dict, Any, Tuple

logger = logging.getLogger(__name__)

# Add lib path for waveshare DS3231
script_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(script_dir)
rtc_lib_path = os.path.join(parent_dir, 'RTC', 'python', 'lib')

if os.path.exists(rtc_lib_path):
    sys.path.insert(0, rtc_lib_path)

class RTCManager:
    """Manager for DS3231 RTC operations"""
    
    def __init__(self, i2c_address: int = 0x68, i2c_bus: int = 1, mock: bool = False):
        self.i2c_address = i2c_address
        self.i2c_bus = i2c_bus
        self.mock = mock
        self.rtc = None
        self._available = False
        
        if not mock:
            self._init_rtc()
    
    def _init_rtc(self):
        """Initialize RTC connection"""
        try:
            from waveshare_DS3231 import DS3231
            self.rtc = DS3231.DS3231(self.i2c_address)
            self._available = True
            logger.info(f"RTC initialized at address 0x{self.i2c_address:02X}")
        except Exception as e:
            logger.error(f"Failed to initialize RTC: {e}")
            self._available = False
    
    @property
    def available(self) -> bool:
        """Check if RTC is available"""
        return self._available or self.mock
    
    def read_time(self) -> Optional[Dict[str, Any]]:
        """Read current time from RTC"""
        if self.mock:
            now = datetime.now()
            return {
                "hour": now.hour,
                "minute": now.minute,
                "second": now.second,
                "mock": True
            }
        
        if not self.rtc:
            return None
        
        try:
            time_data = self.rtc.Read_Time()
            return {
                "hour": time_data[0],
                "minute": time_data[1],
                "second": time_data[2],
                "mock": False
            }
        except Exception as e:
            logger.error(f"Failed to read time: {e}")
            return None
    
    def read_date(self) -> Optional[Dict[str, Any]]:
        """Read current date from RTC"""
        if self.mock:
            now = datetime.now()
            return {
                "year": now.year,
                "month": now.month,
                "day": now.day,
                "mock": True
            }
        
        if not self.rtc:
            return None
        
        try:
            date_data = self.rtc.Read_Calendar()
            return {
                "year": date_data[0],
                "month": date_data[1],
                "day": date_data[2],
                "mock": False
            }
        except Exception as e:
            logger.error(f"Failed to read date: {e}")
            return None
    
    def read_temperature(self) -> Optional[Dict[str, Any]]:
        """Read temperature from RTC sensor"""
        if self.mock:
            return {"temperature": 25.0, "mock": True}
        
        if not self.rtc:
            return None
        
        try:
            temp = self.rtc.Read_Temperature()
            return {
                "temperature": temp,
                "mock": False
            }
        except Exception as e:
            logger.error(f"Failed to read temperature: {e}")
            return None
    
    def set_time(self, hour: int, minute: int, second: int) -> bool:
        """Set time on RTC"""
        if self.mock:
            logger.info(f"Mock: Time set to {hour:02d}:{minute:02d}:{second:02d}")
            return True
        
        if not self.rtc:
            logger.warning("RTC not available")
            return False
        
        try:
            self.rtc.SET_Time(hour, minute, second)
            logger.info(f"Time set to {hour:02d}:{minute:02d}:{second:02d}")
            return True
        except Exception as e:
            logger.error(f"Failed to set time: {e}")
            return False
    
    def set_date(self, year: int, month: int, day: int) -> bool:
        """Set date on RTC"""
        if self.mock:
            logger.info(f"Mock: Date set to {year}-{month:02d}-{day:02d}")
            return True
        
        if not self.rtc:
            logger.warning("RTC not available")
            return False
        
        try:
            self.rtc.SET_Calendar(year, month, day)
            logger.info(f"Date set to {year}-{month:02d}-{day:02d}")
            return True
        except Exception as e:
            logger.error(f"Failed to set date: {e}")
            return False
    
    def set_datetime(self, dt: datetime) -> bool:
        """Set both date and time from datetime object"""
        time_ok = self.set_time(dt.hour, dt.minute, dt.second)
        date_ok = self.set_date(dt.year, dt.month, dt.day)
        return time_ok and date_ok
    
    def get_datetime(self) -> Optional[datetime]:
        """Get complete datetime from RTC"""
        date_data = self.read_date()
        time_data = self.read_time()
        
        if not date_data or not time_data:
            return None
        
        try:
            return datetime(
                date_data["year"], date_data["month"], date_data["day"],
                time_data["hour"], time_data["minute"], time_data["second"]
            )
        except Exception as e:
            logger.error(f"Failed to create datetime: {e}")
            return None
    
    def sync_to_system(self) -> bool:
        """Sync RTC time to system time"""
        dt = self.get_datetime()
        if not dt:
            return False
        
        try:
            import os
            time_str = dt.strftime("%Y-%m-%d %H:%M:%S")
            os.system(f'sudo date -s "{time_str}"')
            logger.info(f"System time synchronized to: {time_str}")
            return True
        except Exception as e:
            logger.error(f"Failed to sync system time: {e}")
            return False
    
    def sync_from_system(self) -> bool:
        """Sync system time to RTC"""
        now = datetime.now()
        return self.set_datetime(now)
    
    def get_status(self) -> Dict[str, Any]:
        """Get complete RTC status"""
        status = {
            "available": self.available,
            "mock": self.mock,
            "i2c_address": f"0x{self.i2c_address:02X}",
            "i2c_bus": self.i2c_bus
        }
        
        time_data = self.read_time()
        if time_data:
            status["time"] = f"{time_data['hour']:02d}:{time_data['minute']:02d}:{time_data['second']:02d}"
        
        date_data = self.read_date()
        if date_data:
            status["date"] = f"{date_data['year']}-{date_data['month']:02d}-{date_data['day']:02d}"
        
        temp_data = self.read_temperature()
        if temp_data:
            status["temperature"] = temp_data["temperature"]
        
        return status
