from abc import ABC, abstractmethod
from typing import List, Dict, Optional
from datetime import datetime
from stamps.models import Stamp


class IPayrollAdapter(ABC):
    """Abstract base class for payroll system integrations"""
    
    def __init__(self, integration_config: Dict):
        """
        Initialize adapter with integration configuration
        
        Args:
            integration_config: Dictionary containing:
                - api_endpoint: API endpoint URL
                - api_key: API key or client ID
                - api_secret: API secret or client secret
        """
        self.api_endpoint = integration_config.get('api_endpoint', '')
        self.api_key = integration_config.get('api_key', '')
        self.api_secret = integration_config.get('api_secret', '')
    
    @abstractmethod
    def transform_stamp_data(self, stamps: List[Stamp], employee_id: str) -> Dict:
        """
        Transform internal Stamp data to payroll-specific format
        
        Args:
            stamps: List of Stamp objects
            employee_id: External employee ID in payroll system
            
        Returns:
            Payroll-specific data structure
        """
        pass
    
    @abstractmethod
    def submit_timesheet(
        self, 
        employee_id: str, 
        period_start: datetime, 
        period_end: datetime,
        timesheet_data: Dict
    ) -> Dict:
        """
        Submit timesheet data to payroll system
        
        Args:
            employee_id: External employee ID
            period_start: Start date of the period
            period_end: End date of the period
            timesheet_data: Transformed timesheet data
            
        Returns:
            Response with submission status, reference ID, etc.
            {
                'success': bool,
                'reference_id': str,
                'message': str,
                'errors': List[str]
            }
        """
        pass
    
    @abstractmethod
    def validate_credentials(self) -> bool:
        """
        Validate API credentials/connection
        
        Returns:
            True if credentials are valid, False otherwise
        """
        pass
    
    @abstractmethod
    def get_employee_mapping(self, user_id: str) -> Optional[str]:
        """
        Map internal user_id to payroll system employee ID
        
        Args:
            user_id: Internal user UUID
            
        Returns:
            Payroll employee ID or None
        """
        pass
    
    @abstractmethod
    def get_project_mapping(self, project_id: str) -> Optional[str]:
        """
        Map internal project_id to payroll system project/cost center
        
        Args:
            project_id: Internal project UUID
            
        Returns:
            Payroll project code or None
        """
        pass
    
    def _parse_duration(self, duration_str: str) -> float:
        """
        Parse duration string to hours (float)
        
        Supports formats:
        - "8:30" -> 8.5
        - "8.5" -> 8.5
        - "8" -> 8.0
        """
        if not duration_str:
            return 0.0
        
        # Remove 'hrs' suffix if present
        duration_str = duration_str.replace('hrs', '').strip()
        
        # Try HH:MM format
        if ':' in duration_str:
            parts = duration_str.split(':')
            if len(parts) == 2:
                try:
                    hours = int(parts[0])
                    minutes = int(parts[1])
                    return hours + (minutes / 60.0)
                except ValueError:
                    pass
        
        # Try decimal format
        try:
            return float(duration_str)
        except ValueError:
            return 0.0

