import requests
from typing import List, Dict, Optional
from datetime import datetime
from stamps.models import Stamp
from .base import IPayrollAdapter


class ProCounterAdapter(IPayrollAdapter):
    """Adapter for ProCounter payroll system"""
    
    def transform_stamp_data(self, stamps: List[Stamp], employee_id: str) -> Dict:
        """
        Transform Stamp data to ProCounter format
        """
        time_entries = []
        
        for stamp in stamps:
            # Convert duration to HH:MM format for ProCounter
            hours_str = self._format_duration_for_procounter(stamp.duration) if stamp.duration else "0:00"
            
            # Get project mapping
            job_code = None
            if stamp.project:
                job_code = self.get_project_mapping(str(stamp.project.id))
            
            # Get task mapping
            activity_code = None
            if stamp.task:
                activity_code = stamp.task.code if hasattr(stamp.task, 'code') else None
            
            entry = {
                "day": stamp.date.isoformat(),
                "hours": hours_str,
                "job_code": job_code,
                "activity_code": activity_code,
                "notes": stamp.description or ""
            }
            time_entries.append(entry)
        
        return {
            "timesheet_submission": {
                "employee_number": employee_id,
                "time_entries": time_entries
            }
        }
    
    def submit_timesheet(
        self, 
        employee_id: str, 
        period_start: datetime, 
        period_end: datetime,
        timesheet_data: Dict
    ) -> Dict:
        """
        Submit timesheet to ProCounter API
        """
        try:
            # ProCounter API endpoint
            url = f"{self.api_endpoint}/api/timesheet/submit"
            
            # Calculate week ending date (typically Saturday)
            week_ending = self._calculate_week_ending(period_end)
            
            payload = {
                "employee_number": employee_id,
                "week_ending": week_ending.isoformat(),
                **timesheet_data
            }
            
            headers = {
                "X-API-Key": self.api_key,
                "Content-Type": "application/json"
            }
            
            response = requests.post(url, json=payload, headers=headers, timeout=30)
            
            if response.status_code == 200:
                data = response.json()
                return {
                    'success': True,
                    'reference_id': data.get('submission_id', ''),
                    'message': 'Timesheet submitted successfully',
                    'errors': []
                }
            else:
                return {
                    'success': False,
                    'reference_id': '',
                    'message': f'API returned status {response.status_code}',
                    'errors': [response.text]
                }
        except requests.exceptions.RequestException as e:
            return {
                'success': False,
                'reference_id': '',
                'message': f'Network error: {str(e)}',
                'errors': [str(e)]
            }
        except Exception as e:
            return {
                'success': False,
                'reference_id': '',
                'message': f'Unexpected error: {str(e)}',
                'errors': [str(e)]
            }
    
    def validate_credentials(self) -> bool:
        """
        Validate ProCounter API credentials
        """
        try:
            url = f"{self.api_endpoint}/api/auth/validate"
            headers = {
                "X-API-Key": self.api_key,
                "Content-Type": "application/json"
            }
            
            response = requests.get(url, headers=headers, timeout=10)
            return response.status_code == 200
        except Exception:
            return False
    
    def get_employee_mapping(self, user_id: str) -> Optional[str]:
        """
        This should be implemented by the service layer using EmployeeMapping model
        For now, return None as this requires database access
        """
        return None
    
    def get_project_mapping(self, project_id: str) -> Optional[str]:
        """
        This should be implemented by the service layer using ProjectMapping model
        For now, return None as this requires database access
        """
        return None
    
    def _format_duration_for_procounter(self, duration_str: str) -> str:
        """
        Convert duration to HH:MM format for ProCounter
        """
        hours = self._parse_duration(duration_str)
        h = int(hours)
        m = int((hours - h) * 60)
        return f"{h}:{m:02d}"
    
    def _calculate_week_ending(self, date: datetime) -> datetime:
        """
        Calculate week ending date (Saturday) for ProCounter
        """
        days_until_saturday = (5 - date.weekday()) % 7
        if days_until_saturday == 0:
            days_until_saturday = 7
        from datetime import timedelta
        return date + timedelta(days=days_until_saturday)

