from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import date, datetime
from enum import Enum

from models.task import TaskType, TaskStatus, ReviewDecision, AttachmentType
from models.user import DepartmentRole


class TaskBase(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    description: Optional[str] = None
    task_type: str  # Changed from TaskType enum to str to support custom task types
    deadline: Optional[date] = None
    status: str = "not_started"  # Changed from TaskStatus enum to str to support custom statuses


class TaskCreate(TaskBase):
    project_id: int
    episode_id: Optional[int] = None
    shot_id: Optional[int] = None
    asset_id: Optional[int] = None
    assigned_user_id: Optional[int] = None


class TaskUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=255)
    description: Optional[str] = None
    task_type: Optional[str] = None  # Changed from TaskType enum to str to support custom task types
    deadline: Optional[date] = None
    status: Optional[str] = None  # Changed from TaskStatus enum to str to support custom statuses
    assigned_user_id: Optional[int] = None


class TaskStatusUpdate(BaseModel):
    status: str  # Changed from TaskStatus enum to str to support custom statuses


class TaskAssignment(BaseModel):
    assigned_user_id: int


class TaskResponse(TaskBase):
    id: int
    project_id: int
    episode_id: Optional[int] = None
    shot_id: Optional[int] = None
    asset_id: Optional[int] = None
    assigned_user_id: Optional[int] = None
    created_at: datetime
    updated_at: datetime
    
    # Related entity names for display
    project_name: Optional[str] = None
    episode_name: Optional[str] = None
    shot_name: Optional[str] = None
    asset_name: Optional[str] = None
    assigned_user_name: Optional[str] = None
    assigned_user_email: Optional[str] = None
    assigned_user_avatar_url: Optional[str] = None

    class Config:
        from_attributes = True


class TaskListResponse(BaseModel):
    id: int
    name: str
    task_type: str  # Changed from TaskType enum to str to support custom task types
    status: str  # Changed from TaskStatus enum to str to support custom statuses
    deadline: Optional[date] = None
    project_id: int
    project_name: str
    episode_id: Optional[int] = None
    episode_name: Optional[str] = None
    shot_id: Optional[int] = None
    shot_name: Optional[str] = None
    asset_id: Optional[int] = None
    asset_name: Optional[str] = None
    assigned_user_id: Optional[int] = None
    assigned_user_name: Optional[str] = None
    assigned_user_avatar_url: Optional[str] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# Production Notes schemas
class ProductionNoteBase(BaseModel):
    content: str = Field(..., min_length=1)
    parent_note_id: Optional[int] = None


class ProductionNoteCreate(ProductionNoteBase):
    pass


class ProductionNoteUpdate(BaseModel):
    content: str = Field(..., min_length=1)


class ProductionNoteResponse(ProductionNoteBase):
    id: int
    task_id: int
    user_id: int
    created_at: datetime
    updated_at: datetime
    
    # User information
    user_first_name: str
    user_last_name: str
    user_email: str
    user_avatar_url: Optional[str] = None
    
    # Child notes for threading
    child_notes: Optional[List['ProductionNoteResponse']] = None

    class Config:
        from_attributes = True


# Task Attachment schemas
class TaskAttachmentBase(BaseModel):
    file_name: str
    attachment_type: AttachmentType = AttachmentType.REFERENCE
    description: Optional[str] = None


class TaskAttachmentCreate(TaskAttachmentBase):
    pass


class TaskAttachmentResponse(TaskAttachmentBase):
    id: int
    task_id: int
    user_id: int
    file_path: str
    file_type: str
    file_size: int
    uploaded_at: datetime
    
    # User information
    user_first_name: str
    user_last_name: str
    
    # File serving URLs (computed properties)
    download_url: Optional[str] = None
    thumbnail_url: Optional[str] = None

    class Config:
        from_attributes = True


# Submission schemas
class SubmissionBase(BaseModel):
    notes: Optional[str] = None


class SubmissionCreate(SubmissionBase):
    pass


class SubmissionResponse(SubmissionBase):
    id: int
    task_id: int
    user_id: int
    file_path: str
    file_name: str
    version_number: int
    submitted_at: datetime
    
    # User information
    user_first_name: str
    user_last_name: str
    
    # Latest review if any
    latest_review: Optional['ReviewResponse'] = None
    
    # File serving URLs (computed properties)
    download_url: Optional[str] = None
    thumbnail_url: Optional[str] = None
    stream_url: Optional[str] = None

    class Config:
        from_attributes = True


# Review schemas
class ReviewBase(BaseModel):
    decision: ReviewDecision
    feedback: Optional[str] = None


class ReviewCreate(ReviewBase):
    pass


class ReviewResponse(ReviewBase):
    id: int
    submission_id: int
    reviewer_id: int
    reviewed_at: datetime
    
    # Reviewer information
    reviewer_first_name: str
    reviewer_last_name: str

    class Config:
        from_attributes = True


# Bulk action schemas
class BulkStatusUpdate(BaseModel):
    task_ids: List[int] = Field(..., min_length=1)
    status: TaskStatus


class BulkAssignment(BaseModel):
    task_ids: List[int] = Field(..., min_length=1)
    assigned_user_id: int


class BulkActionResult(BaseModel):
    success_count: int
    failed_count: int
    errors: Optional[List[dict]] = None


# Update forward references
ProductionNoteResponse.model_rebuild()
SubmissionResponse.model_rebuild()