"""
Availability Model for Worker Scheduling
"""

from datetime import datetime, time
from sqlalchemy import Index
from app.extensions import db
from app.models.base import BaseModel
import json


class AvailabilityStatus:
    """Availability status constants"""
    AVAILABLE = 'available'
    BUSY = 'busy'
    HOLIDAY = 'holiday'
    SICK = 'sick'
    UNAVAILABLE = 'unavailable'


class Availability(BaseModel):
    """Model for worker availability slots"""
    __tablename__ = 'availability'
    
    # Relationships
    worker_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    worker = db.relationship('User', backref='availability_slots', foreign_keys=[worker_id])
    
    # Date and time fields
    date = db.Column(db.Date, nullable=False)
    start_time = db.Column(db.Time, nullable=False)
    end_time = db.Column(db.Time, nullable=False)
    
    # Status and type
    status = db.Column(db.String(20), default=AvailabilityStatus.AVAILABLE, nullable=False)
    is_recurring = db.Column(db.Boolean, default=False)
    recurrence_pattern = db.Column(db.Text)  # JSON: {type: 'weekly', days: [1,3,5], end_date: '2025-12-31'}
    
    # Additional settings
    max_bookings = db.Column(db.Integer, default=1)  # How many bookings allowed in this slot
    current_bookings = db.Column(db.Integer, default=0)
    buffer_time = db.Column(db.Integer, default=30)  # Minutes of buffer time after booking
    
    # Notes
    notes = db.Column(db.Text)
    
    # Indexes for faster queries
    __table_args__ = (
        Index('idx_availability_worker_date', 'worker_id', 'date'),
        Index('idx_availability_date_status', 'date', 'status'),
    )
    
    def to_dict(self):
        """Convert to dictionary for API responses"""
        return {
            'id': self.id,
            'worker_id': self.worker_id,
            'date': self.date.isoformat() if self.date else None,
            'start_time': self.start_time.isoformat() if self.start_time else None,
            'end_time': self.end_time.isoformat() if self.end_time else None,
            'status': self.status,
            'is_recurring': self.is_recurring,
            'recurrence_pattern': json.loads(self.recurrence_pattern) if self.recurrence_pattern else None,
            'max_bookings': self.max_bookings,
            'current_bookings': self.current_bookings,
            'buffer_time': self.buffer_time,
            'notes': self.notes,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None
        }
    
    def is_available(self):
        """Check if slot is available for booking"""
        return (self.status == AvailabilityStatus.AVAILABLE and 
                self.current_bookings < self.max_bookings)
    
    def book_slot(self):
        """Book this availability slot"""
        if self.is_available():
            self.current_bookings += 1
            if self.current_bookings >= self.max_bookings:
                self.status = AvailabilityStatus.BUSY
            return True
        return False
    
    def release_slot(self):
        """Release a booking from this slot"""
        if self.current_bookings > 0:
            self.current_bookings -= 1
            if self.status == AvailabilityStatus.BUSY and self.current_bookings < self.max_bookings:
                self.status = AvailabilityStatus.AVAILABLE
            return True
        return False


class WorkerSchedulePreferences(BaseModel):
    """Model for worker scheduling preferences"""
    __tablename__ = 'worker_schedule_preferences'
    
    worker_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, unique=True)
    worker = db.relationship('User', backref='schedule_preferences', foreign_keys=[worker_id])
    
    # Working hours preferences
    default_start_time = db.Column(db.Time, default=time(9, 0))
    default_end_time = db.Column(db.Time, default=time(17, 0))
    
    # Working days (JSON array of weekday numbers: 0=Monday, 6=Sunday)
    working_days = db.Column(db.Text, default='[1,2,3,4,5]')  # Monday to Friday
    
    # Buffer settings
    default_buffer_time = db.Column(db.Integer, default=30)  # Minutes
    travel_time_buffer = db.Column(db.Integer, default=15)  # Minutes for travel
    
    # Booking settings
    min_advance_booking = db.Column(db.Integer, default=24)  # Hours
    max_advance_booking = db.Column(db.Integer, default=720)  # Hours (30 days)
    
    # Calendar sync settings
    google_calendar_id = db.Column(db.String(255))
    outlook_calendar_id = db.Column(db.String(255))
    sync_enabled = db.Column(db.Boolean, default=False)
    last_sync = db.Column(db.DateTime)
    
    # Notification preferences
    reminder_time = db.Column(db.Integer, default=60)  # Minutes before appointment
    reminder_method = db.Column(db.String(20), default='email')  # email, sms, push
    
    def to_dict(self):
        """Convert to dictionary"""
        return {
            'worker_id': self.worker_id,
            'default_start_time': self.default_start_time.isoformat() if self.default_start_time else None,
            'default_end_time': self.default_end_time.isoformat() if self.default_end_time else None,
            'working_days': json.loads(self.working_days) if self.working_days else [],
            'default_buffer_time': self.default_buffer_time,
            'travel_time_buffer': self.travel_time_buffer,
            'min_advance_booking': self.min_advance_booking,
            'max_advance_booking': self.max_advance_booking,
            'sync_enabled': self.sync_enabled,
            'reminder_time': self.reminder_time,
            'reminder_method': self.reminder_method
        }
