from __future__ import annotations
from datetime import date, datetime
from typing import Optional, List, Any
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
from ..models import ChoreFrequencyEnum, ChoreTypeEnum, ChoreHistoryEventTypeEnum
from .user import UserPublic

class ChoreAssignmentPublic(BaseModel):
    pass

class ChoreHistoryPublic(BaseModel):
    id: int
    event_type: ChoreHistoryEventTypeEnum
    event_data: Optional[dict[str, Any]] = None
    changed_by_user: Optional[UserPublic] = None
    timestamp: datetime

    model_config = ConfigDict(from_attributes=True)

class ChoreAssignmentHistoryPublic(BaseModel):
    id: int
    event_type: ChoreHistoryEventTypeEnum
    event_data: Optional[dict[str, Any]] = None
    changed_by_user: Optional[UserPublic] = None
    timestamp: datetime

    model_config = ConfigDict(from_attributes=True)


class ChoreBase(BaseModel):
    name: str
    description: Optional[str] = None
    frequency: ChoreFrequencyEnum
    custom_interval_days: Optional[int] = None
    next_due_date: date # For creation, this will be the initial due date
    type: ChoreTypeEnum

    @model_validator(mode='after')
    def validate_custom_frequency(self):
        if self.frequency == ChoreFrequencyEnum.custom:
            if self.custom_interval_days is None or self.custom_interval_days <= 0:
                raise ValueError("custom_interval_days must be a positive integer when frequency is 'custom'")
        return self

class ChoreCreate(ChoreBase):
    group_id: Optional[int] = None
    parent_chore_id: Optional[int] = None
    assigned_to_user_id: Optional[int] = None

    @model_validator(mode='after')
    def validate_group_id_with_type(self):
        if self.type == ChoreTypeEnum.group and self.group_id is None:
            raise ValueError("group_id is required for group chores")
        if self.type == ChoreTypeEnum.personal and self.group_id is not None:
            # Automatically clear group_id for personal chores instead of raising an error
            self.group_id = None
        return self

class ChoreUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    frequency: Optional[ChoreFrequencyEnum] = None
    custom_interval_days: Optional[int] = None
    next_due_date: Optional[date] = None # Allow updating next_due_date directly if needed
    type: Optional[ChoreTypeEnum] = None
    group_id: Optional[int] = None
    parent_chore_id: Optional[int] = None  # Allow moving a chore under a parent or removing association
    # last_completed_at should generally not be updated directly by user

    @model_validator(mode='after')
    def validate_group_id_with_type(self):
        if self.type == ChoreTypeEnum.group and self.group_id is None:
            raise ValueError("group_id is required for group chores")
        if self.type == ChoreTypeEnum.personal and self.group_id is not None:
            # Automatically clear group_id for personal chores instead of raising an error
            self.group_id = None
        return self

class ChorePublic(ChoreBase):
    id: int
    group_id: Optional[int] = None
    created_by_id: int
    last_completed_at: Optional[datetime] = None
    parent_chore_id: Optional[int] = None
    created_at: datetime
    updated_at: datetime
    creator: Optional[UserPublic] = None # Embed creator UserPublic schema
    assignments: List[ChoreAssignmentPublic] = []
    history: List[ChoreHistoryPublic] = []
    child_chores: List[ChorePublic] = []

    model_config = ConfigDict(from_attributes=True)

# Chore Assignment Schemas
class ChoreAssignmentBase(BaseModel):
    chore_id: int
    assigned_to_user_id: int
    due_date: date

class ChoreAssignmentCreate(ChoreAssignmentBase):
    pass

class ChoreAssignmentUpdate(BaseModel):
    # Only completion status and perhaps due_date can be updated for an assignment
    is_complete: Optional[bool] = None
    due_date: Optional[date] = None # If rescheduling an existing assignment is allowed
    assigned_to_user_id: Optional[int] = None # For reassigning the chore

class ChoreAssignmentPublic(ChoreAssignmentBase):
    id: int
    is_complete: bool
    completed_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime
    # Embed ChorePublic and UserPublic for richer responses
    chore: Optional[ChorePublic] = None
    assigned_user: Optional[UserPublic] = None
    history: List[ChoreAssignmentHistoryPublic] = []

    model_config = ConfigDict(from_attributes=True)

# To handle potential circular imports if ChorePublic needs GroupPublic and GroupPublic needs ChorePublic
# We can update forward refs after all models are defined.
ChorePublic.model_rebuild()
ChoreAssignmentPublic.model_rebuild()
