"""
Fudging Report Service - Reports fudging events to API

This service reports fudging detection events to the hardware event API.
Includes daily rate limiting (max once per day).
"""

import time
import platform
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from ws_package.log.writer import LogWriter
from ws_package.services.api_request_service import APIRequest
from ws_package.utils.api_log_policy import api_name_from_url
from ws_package.configs import config

logger = LogWriter.file(__name__)


class FudgingReportService:
    """
    Service for reporting fudging events to API.
    
    Features:
    - Daily rate limiting (max once per day)
    - Fail-safe error handling
    - Automatic retry with backoff
    """
    
    def __init__(self):
        self._enabled = config('fudging_api_reporting_enabled', 'ActivityMonitor') or False
        self._api_url = "https://desktop-api.workstatus.io/api/hardware/event"
        
        # Daily rate limiting
        self._last_report_date = None
        self._last_report_timestamp = None
        
        # Device type detection
        self._device_type = self._get_device_type()
    
    def _get_device_type(self) -> str:
        """Get device type string for API"""
        try:
            system = platform.system()
            if system == "Windows":
                return "Windows"
            elif system == "Darwin":
                return "macOS"
            elif system == "Linux":
                return "Linux"
            else:
                return system
        except Exception:
            return "Unknown"
    
    def _get_os_type_caps(self) -> str:
        """Get OS type in caps format (for compatibility)"""
        try:
            system = platform.system()
            if system == "Darwin":
                return "Mac"
            return system.upper()
        except Exception:
            return "UNKNOWN"
    
    def _can_report_today(self) -> bool:
        """Check if we can report today (daily limit)"""
        try:
            today = datetime.now().date()
            
            # If never reported, allow
            if self._last_report_date is None:
                return True
            
            # If reported today, deny
            if self._last_report_date == today:
                return False
            
            # If reported on different day, allow
            return True
        except Exception as e:
            logger.debug("Error checking daily limit (allowing report): %s", e)
            return True  # Fail-safe: allow report
    
    def _mark_reported(self):
        """Mark that we've reported today"""
        try:
            self._last_report_date = datetime.now().date()
            self._last_report_timestamp = time.time()
        except Exception:
            pass  # Fail silently
    
    async def report_fudging(
        self,
        fudging_type: str,
        fudging_score: float,
        reduction_factor: float,
        activity_before: float,
        activity_after: float,
        keyboard_count: int = 0,
        mouse_count: int = 0,
        fudged_duration_seconds: float = 0.0,
        details: Optional[Dict[str, Any]] = None
    ) -> bool:
        """
        Report fudging event to API.
        
        Args:
            fudging_type: Type of fudging detected
            fudging_score: Confidence score (0.0 to 1.0)
            reduction_factor: Current activity reduction factor
            activity_before: Activity percentage before reduction
            activity_after: Activity percentage after reduction
            keyboard_count: Number of keyboard events
            mouse_count: Number of mouse events
            details: Additional details dictionary
        
        Returns:
            True if reported successfully, False otherwise
        """
        if not self._enabled:
            return False
        
        # Check daily limit
        if not self._can_report_today():
            logger.info("")
            logger.info("-" * 80)
            logger.info("*** FUDGING REPORT SKIPPED - DAILY LIMIT REACHED ***")
            logger.info("(Maximum one report per day - already reported today)")
            logger.info("Fudging type: %s", fudging_type)
            logger.info("-" * 80)
            logger.info("")
            return False
        
        try:
            # Build payload
            payload = {
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "device_type": self._device_type,
                "fudging_type": fudging_type,
                "fudging_score": fudging_score,
                "reduction_factor": reduction_factor,
                "activity_before": activity_before,
                "activity_after": activity_after,
                "keyboard_count": keyboard_count,
                "mouse_count": mouse_count,
                "fudged_duration_seconds": fudged_duration_seconds,
                "fudged_duration_minutes": fudged_duration_seconds / 60.0,
                "details": details or {}
            }
            
            # Headers
            headers = {
                "deviceType": self._get_os_type_caps(),
                "Content-Type": "application/json"
            }
            
            # Make API call (synchronous for now)
            api_label = api_name_from_url(self._api_url)
            logger.info("Sending fudging report (%s, type=%s)", api_label, fudging_type)
            
            api_request = APIRequest(url=self._api_url, headers=headers, timeout=10)
            api_request.post(payload)
            
            # Check response
            if api_request.response and api_request.response.status_code == 200:
                logger.info("Fudging report sent successfully (%s, type=%s)", api_label, fudging_type)
                self._mark_reported()
                return True
            else:
                status = api_request.response.status_code if api_request.response else "no response"
                logger.warning("Fudging report failed (%s, type=%s, HTTP=%s)", api_label, fudging_type, status)
                return False
                
        except Exception as e:
            logger.error("Error reporting fudging event (fail-safe): %s", e)
            return False  # Fail-safe: return False, don't crash


# Global singleton instance
_fudging_report_service = None

def get_fudging_report_service() -> FudgingReportService:
    """Get the global fudging report service instance"""
    global _fudging_report_service
    if _fudging_report_service is None:
        _fudging_report_service = FudgingReportService()
    return _fudging_report_service

