from beanie import Document, PydanticObjectId
from pydantic import Field, HttpUrl
from typing import Optional, Dict, Any, List
from datetime import datetime, date
from enum import Enum

class ProfileVisibility(str, Enum):
    PUBLIC = "public"
    PRIVATE = "private"
    FRIENDS_ONLY = "friends_only"

class ProfileStatus(str, Enum):
    ACTIVE = "active"
    INCOMPLETE = "incomplete"
    SUSPENDED = "suspended"

class UserProfile(Document):
    # Link to auth service user
    user_id: PydanticObjectId  # References User from auth service
    email: str  # Denormalized for quick lookup
    username: str  # Denormalized for quick lookup
    
    # Basic Information
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    display_name: Optional[str] = None
    bio: Optional[str] = Field(None, max_length=500)
    
    # Contact Information
    phone: Optional[str] = None
    website: Optional[HttpUrl] = None
    
    # Location
    country: Optional[str] = None
    city: Optional[str] = None
    timezone: Optional[str] = "UTC"
    
    # Profile Media
    avatar_url: Optional[str] = None
    cover_photo_url: Optional[str] = None
    
    # Social Links
    social_links: Dict[str, str] = Field(default_factory=dict)
    
    # Personal Details
    birth_date: Optional[date] = None
    gender: Optional[str] = None
    
    # Profile Settings
    visibility: ProfileVisibility = ProfileVisibility.PUBLIC
    status: ProfileStatus = ProfileStatus.ACTIVE
    
    # Profile Statistics
    profile_completion_percentage: int = 0
    followers_count: int = 0
    following_count: int = 0
    posts_count: int = 0
    
    # Metadata
    created_at: datetime = Field(default_factory=datetime.utcnow)
    updated_at: datetime = Field(default_factory=datetime.utcnow)
    last_seen: Optional[datetime] = None
    
    # Additional Data
    custom_fields: Dict[str, Any] = Field(default_factory=dict)
    tags: List[str] = Field(default_factory=list)
    
    class Settings:
        name = "user_profiles"
        indexes = [
            "user_id",
            "email",
            "username", 
            "display_name",
            "status",
            "visibility",
            "created_at",
            "updated_at"
        ]

    class Config:
        arbitrary_types_allowed = True

    def get_full_name(self) -> Optional[str]:
        """Get user's full name"""
        if self.first_name and self.last_name:
            return f"{self.first_name} {self.last_name}"
        elif self.first_name:
            return self.first_name
        elif self.last_name:
            return self.last_name
        return None

    def get_display_name(self) -> str:
        """Get the name to display for this user"""
        if self.display_name:
            return self.display_name
        elif self.get_full_name():
            return self.get_full_name()
        else:
            return self.username

    def calculate_completion_percentage(self) -> int:
        """Calculate profile completion percentage"""
        total_fields = 12  # Number of important fields
        completed_fields = 0
        
        # Check important fields
        if self.first_name: completed_fields += 1
        if self.last_name: completed_fields += 1
        if self.bio: completed_fields += 1
        if self.avatar_url: completed_fields += 1
        if self.phone: completed_fields += 1
        if self.website: completed_fields += 1
        if self.country: completed_fields += 1
        if self.city: completed_fields += 1
        if self.birth_date: completed_fields += 1
        if self.social_links: completed_fields += 1
        if self.tags: completed_fields += 1
        if self.display_name: completed_fields += 1
        
        return int((completed_fields / total_fields) * 100)

    async def update_completion_percentage(self):
        """Update profile completion percentage"""
        self.profile_completion_percentage = self.calculate_completion_percentage()
        
        # Update status based on completion
        if self.profile_completion_percentage >= 70:
            self.status = ProfileStatus.ACTIVE
        else:
            self.status = ProfileStatus.INCOMPLETE
        
        await self.save()

    async def update_last_seen(self):
        """Update last seen timestamp"""
        self.last_seen = datetime.utcnow()
        await self.save()

    def is_public(self) -> bool:
        """Check if profile is public"""
        return self.visibility == ProfileVisibility.PUBLIC

    def can_be_viewed_by(self, viewer_user_id: Optional[PydanticObjectId]) -> bool:
        """Check if profile can be viewed by a specific user"""
        if self.visibility == ProfileVisibility.PUBLIC:
            return True
        elif self.visibility == ProfileVisibility.PRIVATE:
            return viewer_user_id == self.user_id
        elif self.visibility == ProfileVisibility.FRIENDS_ONLY:
            # TODO: Implement friends relationship check
            return viewer_user_id == self.user_id
        return False

    @classmethod
    async def create_from_auth_user(
        cls,
        user_id: PydanticObjectId,
        email: str,
        username: str
    ) -> "UserProfile":
        """Create a profile when user registers in auth service"""
        profile = cls(
            user_id=user_id,
            email=email,
            username=username,
            status=ProfileStatus.INCOMPLETE
        )
        
        await profile.save()
        return profile
