"""
Time Tracking Service Layer for RateRight Australian Construction Marketplace
Provides contract-context hour management and time entry operations
"""

import logging
from datetime import datetime, date, timedelta
from typing import List, Optional, Dict, Any, Tuple
from flask import current_app
from sqlalchemy import func, and_, or_
from sqlalchemy.exc import SQLAlchemyError

from ..extensions import db
from ..models.time_tracking import TimeEntry, Shift, ShiftBid
from ..models.contract import Contract
from ..models.user import User
from ..models.job import Job
from ..models.notification import NotificationType
from .notification_service import notification_service

logger = logging.getLogger(__name__)


class TimeTrackingService:
    """Comprehensive time tracking service with contract integration"""

    def __init__(self):
        self.logger = logger

    # ==================== CONTRACT-CONTEXT HOUR MANAGEMENT ====================

    def get_contract_hours(self, contract_id: int) -> Dict[str, Any]:
        """
        Get comprehensive hour summary for a contract
        
        Args:
            contract_id: ID of the contract
            
        Returns:
            Dictionary containing hour details, entries, and summary
        """
        try:
            # Validate contract exists
            contract = Contract.query.get(contract_id)
            if not contract:
                self.logger.error(f"Contract not found: {contract_id}")
                return {"success": False, "error": "Contract not found"}

            # Get all time entries for the contract
            time_entries = TimeEntry.query.filter_by(
                contract_id=contract_id
            ).order_by(TimeEntry.work_date.desc()).all()

            # Calculate totals
            total_regular = sum(entry.regular_hours or 0 for entry in time_entries)
            total_overtime = sum(entry.overtime_hours or 0 for entry in time_entries)
            total_hours = total_regular + total_overtime
            total_minutes = sum(entry.total_minutes or 0 for entry in time_entries)
            
            # Count approved vs pending
            approved_entries = [e for e in time_entries if e.is_approved]
            pending_entries = [e for e in time_entries if not e.is_approved]
            
            # Calculate approved hours
            approved_hours = sum(entry.regular_hours or 0 for entry in approved_entries)
            approved_overtime = sum(entry.overtime_hours or 0 for entry in approved_entries)
            
            return {
                "success": True,
                "contract_id": contract_id,
                "contract_status": contract.status,
                "can_edit_hours": self._can_edit_contract_hours(contract),
                "summary": {
                    "total_hours": round(total_hours, 2),
                    "total_regular_hours": round(total_regular, 2),
                    "total_overtime_hours": round(total_overtime, 2),
                    "total_minutes": total_minutes,
                    "approved_hours": round((approved_hours + approved_overtime), 2),
                    "approved_overtime_hours": round(approved_overtime, 2),
                    "pending_approval_hours": round(total_hours - approved_hours, 2),
                    "total_entries": len(time_entries),
                    "approved_entries": len(approved_entries),
                    "pending_entries": len(pending_entries)
                },
                "entries": [entry.to_dict() for entry in time_entries],
                "worker_name": f"{contract.worker.first_name} {contract.worker.last_name}",
                "contract_rate": float(contract.agreed_rate),
                "rate_type": contract.rate_type
            }

        except Exception as e:
            self.logger.error(f"Error getting contract hours for {contract_id}: {e}")
            return {"success": False, "error": str(e)}

    def get_worker_contract_hours(self, worker_id: int, contract_id: int) -> Dict[str, Any]:
        """Get hours for specific worker on specific contract"""
        try:
            entries = TimeEntry.query.filter_by(
                worker_id=worker_id,
                contract_id=contract_id
            ).order_by(TimeEntry.work_date.desc()).all()

            total_hours = sum(entry.regular_hours or 0 for entry in entries)
            total_overtime = sum(entry.overtime_hours or 0 for entry in entries)

            return {
                "success": True,
                "entries": [entry.to_dict() for entry in entries],
                "total_hours": round(total_hours, 2),
                "total_overtime_hours": round(total_overtime, 2),
                "total_entries": len(entries)
            }

        except Exception as e:
            self.logger.error(f"Error getting worker contract hours: {e}")
            return {"success": False, "error": str(e)}

    # ==================== TIME ENTRY CRUD OPERATIONS ====================

    def create_time_entry(
        self,
        contract_id: int,
        worker_id: int,
        hours: float,
        work_date: date = None,
        description: str = "",
        location: str = "",
        is_manual_entry: bool = True,
        job_id: int = None,
        booking_id: int = None
    ) -> Dict[str, Any]:
        try:
            # --- Date validation and conversion ---
            from datetime import datetime, date, timedelta
            if isinstance(work_date, str):
                try:
                    work_date = datetime.strptime(work_date, "%d-%m-%Y").date()
                except ValueError:
                    return {"success": False, "error": f"Invalid date format: {work_date}. Expected DD-MM-YYYY"}

            if work_date is None:
                work_date = date.today()

            # --- Hours validation ---
            if hours is None:
                return {"success": False, "error": "Hours value is missing"}

            try:
                hours = float(hours)
            except (TypeError, ValueError):
                return {"success": False, "error": "Hours must be a number"}

            if hours <= 0:
                return {"success": False, "error": "Hours must be greater than 0"}

            if hours > 24:
                return {"success": False, "error": "Hours cannot exceed 24 per day"}
            # Validate contract and worker
            contract = Contract.query.get(contract_id)
            if not contract:
                return {"success": False, "error": "Contract not found"}

            if contract.worker_id != worker_id:
                return {"success": False, "error": "Worker not authorized for this contract"}

            # Check if contract allows hour editing
            if not self._can_edit_contract_hours(contract):
                return {"success": False, "error": "Cannot add hours to this contract"}

            # Use today if no date provided
            if work_date is None:
                work_date = date.today()

            # Check for existing entry on same date
            existing = TimeEntry.query.filter_by(
                contract_id=contract_id,
                worker_id=worker_id,
                work_date=work_date
            ).first()

            if existing:
                return {
                    "success": False, 
                    "error": f"Time entry already exists for {work_date}. Use edit function instead."
                }

            # Calculate regular and overtime hours
            regular_hours = min(hours, 8.0)
            overtime_hours = max(0.0, hours - 8.0)
            total_minutes = int(hours * 60)

            # Create clock times for manual entry
            clock_in = datetime.combine(work_date, datetime.min.time().replace(hour=9))
            clock_out = clock_in + timedelta(hours=hours)

            # Create time entry
            time_entry = TimeEntry(
                worker_id=worker_id,
                job_id=job_id or contract.job_id,
                booking_id=booking_id,
                contract_id=contract_id,
                clock_in=clock_in,
                clock_out=clock_out,
                work_date=work_date,
                description=description,
                location=location,
                total_minutes=total_minutes,
                regular_hours=regular_hours,
                overtime_hours=overtime_hours,
                is_manual_entry=is_manual_entry,
                is_approved=False  # Requires approval
            )

            db.session.add(time_entry)
            db.session.commit()

            # Send notification to contractor about new hours submitted
            try:
                worker = User.query.get(worker_id)
                notification_service.send_notification(
                    user_id=contract.contractor_id,
                    notification_type=NotificationType.HOURS_PENDING_APPROVAL,
                    title="New Hours Submitted",
                    content=f"{worker.first_name} {worker.last_name} submitted {hours} hours for approval on {work_date}"
                )
            except Exception as e:
                self.logger.warning(f"Failed to send notification for new hours: {e}")

            self.logger.info(f"Created time entry {time_entry.id} for contract {contract_id}")

            return {
                "success": True,
                "message": "Time entry updated successfully",
                "regular_hours": round(time_entry.regular_hours or 0, 2),
                "overtime_hours": round(time_entry.overtime_hours or 0, 2),
                "time_entry": time_entry.to_dict()
            }


        except SQLAlchemyError as e:
            db.session.rollback()
            self.logger.error(f"Database error creating time entry: {e}")
            return {"success": False, "error": "Database error occurred"}
        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error creating time entry: {e}")
            return {"success": False, "error": str(e)}

    def edit_time_entry(
        self,
        entry_id: int,
        worker_id=None,
        hours: Optional[float] = None,
        description: Optional[str] = None,
        location: Optional[str] = None,
        work_date: Optional[date] = None,
        user_id: int = None
    ) -> Dict[str, Any]:
        """
        Edit an existing time entry (only allowed before contract completion)
        
        Args:
            entry_id: Time entry ID
            hours: New hours (optional)
            description: New description (optional)
            location: New location (optional)
            work_date: New work date (optional)
            user_id: ID of user making the edit (for authorization)
            
        Returns:
            Dictionary with success status and updated entry
        """
        try:
            # Get time entry
            time_entry = TimeEntry.query.get(entry_id)
            if not time_entry:
                return {"success": False, "error": "Time entry not found"}

            # Check authorization
            if user_id and user_id not in [time_entry.worker_id, time_entry.contract.contractor_id]:
                return {"success": False, "error": "Not authorized to edit this time entry"}
            
            # Authorization check
            if worker_id and time_entry.worker_id != worker_id:
                return {"success": False, "error": "Not authorized"}
            
            # Check if entry can be edited
            if time_entry.is_approved:
                return {"success": False, "error": "Cannot edit approved time entries"}

            # Check contract status
            if not self._can_edit_contract_hours(time_entry.contract):
                return {"success": False, "error": "Cannot edit hours for this contract"}

            # Validate hours if provided
            if hours is not None:
                if hours <= 0:
                    return {"success": False, "error": "Hours must be greater than 0"}
                if hours > 24:
                    return {"success": False, "error": "Hours cannot exceed 24 per day"}

            # Store original values for logging
            original_hours = time_entry.regular_hours + time_entry.overtime_hours
            
            # Update fields
            if hours is not None:
                # Recalculate regular and overtime
                time_entry.regular_hours = min(hours, 8.0)
                time_entry.overtime_hours = max(0.0, hours - 8.0)
                time_entry.total_minutes = int(hours * 60)
                
                # Update clock out time to match new hours
                if time_entry.clock_in:
                    time_entry.clock_out = time_entry.clock_in + timedelta(hours=hours)

            if description is not None:
                time_entry.description = description

            if location is not None:
                time_entry.location = location

            if work_date is not None:
                time_entry.work_date = work_date
                # Update clock times if work date changes
                if time_entry.clock_in:
                    total_hours = hours or (original_hours)
                    time_entry.clock_in = datetime.combine(work_date, datetime.min.time().replace(hour=9))
                    time_entry.clock_out = time_entry.clock_in + timedelta(hours=total_hours)

            db.session.commit()

            self.logger.info(f"Edited time entry {entry_id}: hours {original_hours} -> {hours or original_hours}")

            return {
                "success": True,
                "time_entry": time_entry.to_dict(),
                "message": "Time entry updated successfully"
            }

        except SQLAlchemyError as e:
            db.session.rollback()
            self.logger.error(f"Database error editing time entry: {e}")
            return {"success": False, "error": "Database error occurred"}
        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error editing time entry {entry_id}: {e}")
            return {"success": False, "error": str(e)}

    def delete_time_entry(self, entry_id: int, user_id: int = None) -> Dict[str, Any]:
        """Delete a time entry (only if not approved and contract allows editing)"""
        try:
            time_entry = TimeEntry.query.get(entry_id)
            if not time_entry:
                return {"success": False, "error": "Time entry not found"}

            # Check authorization
            if user_id and user_id not in [time_entry.worker_id, time_entry.contract.contractor_id]:
                return {"success": False, "error": "Not authorized to delete this time entry"}

            # Check if entry can be deleted
            if time_entry.is_approved:
                return {"success": False, "error": "Cannot delete approved time entries"}

            if not self._can_edit_contract_hours(time_entry.contract):
                return {"success": False, "error": "Cannot delete hours for this contract"}

            db.session.delete(time_entry)
            db.session.commit()

            self.logger.info(f"Deleted time entry {entry_id}")

            return {"success": True, "message": "Time entry deleted successfully"}

        except SQLAlchemyError as e:
            db.session.rollback()
            self.logger.error(f"Database error deleting time entry: {e}")
            return {"success": False, "error": "Database error occurred"}
        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error deleting time entry {entry_id}: {e}")
            return {"success": False, "error": str(e)}

    # ==================== CLOCK IN/OUT WORKFLOW ====================

    def clock_in(self, worker_id: int, contract_id: int, location: str = "", description: str = "") -> Dict[str, Any]:
        """Clock in a worker for a contract"""
        try:
            # Validate contract
            contract = Contract.query.get(contract_id)
            if not contract:
                return {"success": False, "error": "Contract not found"}

            if contract.worker_id != worker_id:
                return {"success": False, "error": "Worker not authorized for this contract"}

            if contract.status != 'active':
                return {"success": False, "error": "Cannot clock in on inactive contract"}

            # Check for existing active clock-in
            today = date.today()
            existing_entry = TimeEntry.query.filter_by(
                worker_id=worker_id,
                contract_id=contract_id,
                work_date=today
            ).filter(TimeEntry.clock_out.is_(None)).first()

            if existing_entry:
                return {"success": False, "error": "Already clocked in for today"}

            # Create new time entry
            time_entry = TimeEntry(
                worker_id=worker_id,
                job_id=contract.job_id,
                contract_id=contract_id,
                clock_in=datetime.utcnow(),
                work_date=today,
                description=description,
                location=location,
                is_manual_entry=False,
                is_approved=False
            )

            db.session.add(time_entry)
            db.session.commit()

            self.logger.info(f"Worker {worker_id} clocked in for contract {contract_id}")

            return {
                "success": True,
                "time_entry": time_entry.to_dict(),
                "message": f"Clocked in at {time_entry.clock_in.strftime('%H:%M')}"
            }

        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error clocking in: {e}")
            return {"success": False, "error": str(e)}

    def clock_out(self, worker_id: int, entry_id: int = None, description: str = "") -> Dict[str, Any]:
        """Clock out a worker"""
        try:
            # Find active entry
            if entry_id:
                time_entry = TimeEntry.query.get(entry_id)
                if not time_entry or time_entry.worker_id != worker_id:
                    return {"success": False, "error": "Time entry not found or not authorized"}
            else:
                # Find today's unclosed entry
                today = date.today()
                time_entry = TimeEntry.query.filter_by(
                    worker_id=worker_id,
                    work_date=today
                ).filter(TimeEntry.clock_out.is_(None)).first()

                if not time_entry:
                    return {"success": False, "error": "No active clock-in found for today"}

            # Clock out
            success = time_entry.clock_out_now()
            if not success:
                return {"success": False, "error": "Already clocked out or not clocked in"}

            # Update description if provided
            if description:
                time_entry.description = description

            db.session.commit()

            total_hours = (time_entry.regular_hours or 0) + (time_entry.overtime_hours or 0)
            
            # Check for overtime and send alert if needed
            if total_hours > 8:
                overtime_hours = total_hours - 8
                try:
                    # Notify both worker and contractor about overtime
                    notification_service.send_bulk_notifications(
                        user_ids=[worker_id, time_entry.contract.contractor_id],
                        notification_type=NotificationType.OVERTIME_ALERT,
                        title="Overtime Alert",
                        content=f"Overtime detected: {overtime_hours:.2f} hours worked (Total: {total_hours:.2f} hours)"
                    )
                except Exception as e:
                    self.logger.warning(f"Failed to send overtime alert: {e}")
            
            self.logger.info(f"Worker {worker_id} clocked out from entry {time_entry.id}")

            return {
                "success": True,
                "time_entry": time_entry.to_dict(),
                "total_hours": round(total_hours, 2),
                "message": f"Clocked out at {time_entry.clock_out.strftime('%H:%M')} - Total: {total_hours:.2f} hours"
            }

        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error clocking out: {e}")
            return {"success": False, "error": str(e)}

    def get_active_clock_in(self, worker_id: int) -> Optional[Dict[str, Any]]:
        """Get worker's active clock-in for today"""
        try:
            today = date.today()
            active_entry = TimeEntry.query.filter_by(
                worker_id=worker_id,
                work_date=today
            ).filter(TimeEntry.clock_out.is_(None)).first()

            if active_entry:
                return {
                    "active": True,
                    "entry": active_entry.to_dict(),
                    "duration_minutes": int((datetime.utcnow() - active_entry.clock_in).total_seconds() / 60)
                }

            return {"active": False}

        except Exception as e:
            self.logger.error(f"Error getting active clock-in: {e}")
            return {"active": False, "error": str(e)}

    # ==================== APPROVAL WORKFLOW ====================

    def approve_time_entries(self, contract_id: int, approver_id: int, entry_ids: List[int] = None) -> Dict[str, Any]:
        """
        Approve time entries for a contract
        
        Args:
            contract_id: Contract ID
            approver_id: User ID of the approver
            entry_ids: Specific entry IDs to approve (if None, approves all pending)
            
        Returns:
            Dictionary with approval results
        """
        try:
            # Validate contract and authorization
            contract = Contract.query.get(contract_id)
            if not contract:
                return {"success": False, "error": "Contract not found"}

            # Check if approver is authorized (contractor)
            if contract.contractor_id != approver_id:
                return {"success": False, "error": "Not authorized to approve time entries for this contract"}

            # Get entries to approve
            query = TimeEntry.query.filter_by(contract_id=contract_id, is_approved=False)
            
            if entry_ids:
                query = query.filter(TimeEntry.id.in_(entry_ids))
            
            entries_to_approve = query.all()

            if not entries_to_approve:
                return {"success": False, "error": "No pending time entries to approve"}

            # Approve entries
            approved_count = 0
            approved_hours = 0
            
            for entry in entries_to_approve:
                success = entry.approve(approver_id)
                if success:
                    approved_count += 1
                    approved_hours += (entry.regular_hours or 0) + (entry.overtime_hours or 0)

            db.session.commit()
            # --- NEW: update contract.review_hours_status if all time entries approved ---
            pending = TimeEntry.query.filter_by(contract_id=contract_id, is_approved=False).count()
            if pending == 0 and contract.review_hours_status != 'ready_for_closeout':
                contract.review_hours_status = 'ready_for_closeout'
                db.session.commit()
                self.logger.info(f"Contract {contract_id} review_hours_status set to ready_for_closeout")

            # Send notification to worker about approved hours
            try:
                notification_service.send_notification(
                    user_id=contract.worker_id,
                    notification_type=NotificationType.HOURS_APPROVED,
                    title="Hours Approved",
                    content=f"Your {approved_hours:.2f} hours have been approved by the contractor"
                )
            except Exception as e:
                self.logger.warning(f"Failed to send approval notification: {e}")

            self.logger.info(f"Approved {approved_count} time entries for contract {contract_id}")

            return {
                "success": True,
                "approved_count": approved_count,
                "approved_hours": round(approved_hours, 2),
                "message": f"Approved {approved_count} time entries totaling {approved_hours:.2f} hours"
            }

        except Exception as e:
            db.session.rollback()
            self.logger.error(f"Error approving time entries: {e}")
            return {"success": False, "error": str(e)}

    def get_pending_approvals(self, contractor_id: int) -> Dict[str, Any]:
        """Get all pending time entry approvals for a contractor (optimized query)"""
        try:
            # Optimized single query with joins to eliminate N+1 query issue
            pending_entries = db.session.query(TimeEntry)\
                .join(Contract, TimeEntry.contract_id == Contract.id)\
                .join(User, TimeEntry.worker_id == User.id)\
                .filter(
                    Contract.contractor_id == contractor_id,
                    TimeEntry.is_approved == False
                )\
                .order_by(TimeEntry.work_date.desc())\
                .all()

            # Group by contract (data already loaded with joins)
            by_contract = {}
            total_pending_hours = 0
            
            for entry in pending_entries:
                contract_id = entry.contract_id
                if contract_id not in by_contract:
                    by_contract[contract_id] = {
                        "contract": entry.contract,  # Already loaded via join
                        "worker_name": f"{entry.worker.first_name} {entry.worker.last_name}",  # Already loaded
                        "entries": [],
                        "total_hours": 0
                    }
                
                by_contract[contract_id]["entries"].append(entry.to_dict())
                entry_hours = (entry.regular_hours or 0) + (entry.overtime_hours or 0)
                by_contract[contract_id]["total_hours"] += entry_hours
                total_pending_hours += entry_hours

            return {
                "success": True,
                "pending_contracts": list(by_contract.values()),
                "total_pending_entries": len(pending_entries),
                "total_pending_hours": round(total_pending_hours, 2)
            }

        except Exception as e:
            self.logger.error(f"Error getting pending approvals: {e}")
            return {"success": False, "error": str(e)}

    # ==================== HOUR CALCULATIONS ====================

    def calculate_total_hours(self, contract_id: int, approved_only: bool = False) -> Dict[str, Any]:
        """
        Calculate total hours for a contract
        
        Args:
            contract_id: Contract ID
            approved_only: Only count approved entries
            
        Returns:
            Dictionary with hour calculations
        """
        try:
            query = TimeEntry.query.filter_by(contract_id=contract_id)
            
            if approved_only:
                query = query.filter_by(is_approved=True)
            
            entries = query.all()

            if not entries:
                return {
                    "success": True,
                    "total_hours": 0,
                    "regular_hours": 0,
                    "overtime_hours": 0,
                    "total_minutes": 0,
                    "total_entries": 0,
                    "date_range": None
                }

            # Calculate totals
            total_regular = sum(entry.regular_hours or 0 for entry in entries)
            total_overtime = sum(entry.overtime_hours or 0 for entry in entries)
            total_minutes = sum(entry.total_minutes or 0 for entry in entries)
            
            # Get date range
            work_dates = [entry.work_date for entry in entries if entry.work_date]
            date_range = {
                "start_date": min(work_dates).isoformat() if work_dates else None,
                "end_date": max(work_dates).isoformat() if work_dates else None
            }

            return {
                "success": True,
                "total_hours": round(total_regular + total_overtime, 2),
                "regular_hours": round(total_regular, 2),
                "overtime_hours": round(total_overtime, 2),
                "total_minutes": total_minutes,
                "total_entries": len(entries),
                "date_range": date_range,
                "approved_only": approved_only
            }

        except Exception as e:
            self.logger.error(f"Error calculating total hours: {e}")
            return {"success": False, "error": str(e)}

    def get_hours_by_date_range(
        self,
        contract_id: int,
        start_date: date,
        end_date: date,
        worker_id: int = None
    ) -> Dict[str, Any]:
        """Get hours worked within a specific date range"""
        try:
            query = TimeEntry.query.filter(
                TimeEntry.contract_id == contract_id,
                TimeEntry.work_date >= start_date,
                TimeEntry.work_date <= end_date
            )
            
            if worker_id:
                query = query.filter_by(worker_id=worker_id)
            
            entries = query.order_by(TimeEntry.work_date.asc()).all()

            # Group by date
            by_date = {}
            total_hours = 0
            
            for entry in entries:
                date_str = entry.work_date.isoformat()
                if date_str not in by_date:
                    by_date[date_str] = {
                        "date": date_str,
                        "entries": [],
                        "daily_hours": 0
                    }
                
                entry_hours = (entry.regular_hours or 0) + (entry.overtime_hours or 0)
                by_date[date_str]["entries"].append(entry.to_dict())
                by_date[date_str]["daily_hours"] += entry_hours
                total_hours += entry_hours

            return {
                "success": True,
                "date_range": {
                    "start_date": start_date.isoformat(),
                    "end_date": end_date.isoformat()
                },
                "by_date": list(by_date.values()),
                "total_hours": round(total_hours, 2),
                "total_days": len(by_date),
                "total_entries": len(entries)
            }

        except Exception as e:
            self.logger.error(f"Error getting hours by date range: {e}")
            return {"success": False, "error": str(e)}

    # ==================== HELPER METHODS ====================

    def _can_edit_contract_hours(self, contract: Contract) -> bool:
        """Check if hours can be edited for a contract"""
        # Allow editing if contract is active or pending review
        allowed_statuses = ['active', 'pending_review']
        return contract.status in allowed_statuses

    def _validate_business_rules(self, time_entry: TimeEntry) -> Tuple[bool, str]:
        """Validate business rules for time entry"""
        try:
            # Check maximum daily hours (Australian workplace limits)
            daily_hours = (time_entry.regular_hours or 0) + (time_entry.overtime_hours or 0)
            if daily_hours > 12:  # Australian maximum daily hours
                return False, "Daily hours cannot exceed 12 hours"

            # Check future dates
            if time_entry.work_date > date.today():
                return False, "Cannot log hours for future dates"

            # Check for reasonable time ranges (not more than 30 days old)
            days_old = (date.today() - time_entry.work_date).days
            if days_old > 30:
                return False, "Cannot log hours more than 30 days old"

            return True, ""

        except Exception as e:
            self.logger.error(f"Error validating business rules: {e}")
            return False, str(e)



# Singleton instance
time_tracking_service = TimeTrackingService()