from datetime import datetime
from enum import Enum
from typing import List, Optional

from pydantic import BaseModel, EmailStr, Field, HttpUrl, constr


class AccountType(str, Enum):
    BANKER = "banker"
    SELLER = "seller"
    BUYER = "buyer"
    VENDOR = "vendor"


class UserBase(BaseModel):
    user_id: str = Field(..., description="Unique identifier for the user")
    username: str = Field(..., min_length=3, max_length=50)
    email: str = Field(..., pattern=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
    first_name: Optional[str] = Field(None, min_length=0, max_length=50)
    last_name: Optional[str] = Field(None, min_length=0, max_length=50)
    phone: Optional[str] = Field(None)
    profile_pic: Optional[str] = Field(None, pattern=r"^https?://[^\s/$.?#].[^\s]*$")
    account_type: AccountType = Field(default=AccountType.BANKER)
    title: Optional[str] = Field(None, min_length=1, max_length=100)
    signature: Optional[str] = Field(None, max_length=300)
    created_at: datetime = Field(default_factory=lambda: datetime.now())
    updated_at: datetime = Field(default_factory=lambda: datetime.now())
    team_id: Optional[str] = Field(default="")
    projects: List[str] = Field(default_factory=list)
    is_active: bool = Field(default=True)
    last_login: Optional[datetime] = None

    def update_modify(self):
        """Update the modified date"""
        self.updated_at = datetime.now()

    def model_dump(self, **kwargs):
        data = super().model_dump(**kwargs)
        data["created_at"] = self.created_at.strftime("%Y-%m-%d %H:%M:%S")

        data["updated_at"] = self.updated_at.strftime("%Y-%m-%d %H:%M:%S")
        if self.last_login:
            data["last_login"] = self.last_login.strftime("%Y-%m-%d %H:%M:%S")
        return data

    def save_to_db(self):
        """Save user to DynamoDB"""
        from utils.dynamo_db import DynamoDB

        db = DynamoDB()
        self.update_modify()
        return db.upload_to_dynamodb(db.dynamodb.Table("user"), self.model_dump())

    @property
    def full_name(self) -> str:
        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 ""

    def update_username(self, new_username: str):
        """Update the username"""
        if len(new_username) < 3 or len(new_username) > 50:
            raise ValueError("Username must be between 3 and 50 characters")
        self.username = new_username
        self.update_modify()

    def update_team(self, new_team_id: Optional[str]):
        """Update the team ID"""
        self.team_id = new_team_id
        self.update_modify()

    def update_account_type(self, new_account_type: AccountType):
        """Update the account type"""
        self.account_type = new_account_type
        self.update_modify()

    def update_profile(
        self,
        first_name: Optional[str] = None,
        last_name: Optional[str] = None,
        phone: Optional[str] = None,
        profile_pic: Optional[str] = None,
        title: Optional[str] = None,
        signature: Optional[str] = None,
    ):
        """Update multiple profile fields at once"""
        if first_name is not None:
            self.first_name = first_name
        if last_name is not None:
            self.last_name = last_name
        if phone is not None:
            self.phone = phone
        if profile_pic is not None:
            self.profile_pic = profile_pic
        if title is not None:
            self.title = title
        if signature is not None:
            self.signature = signature
        self.update_modify()

    def update_last_login(self):
        """Update the last login timestamp"""
        self.last_login = datetime.now()
        self.update_modify()

    def deactivate(self):
        """Deactivate the user"""
        self.is_active = False
        self.update_modify()

    def activate(self):
        """Activate the user"""
        self.is_active = True
        self.update_modify()

    def add_project(self, project_id: str):
        """Add a project ID to the user's projects list"""
        if project_id not in self.projects:
            self.projects.append(project_id)
            self.update_modify()
            self.save_to_db()

    def remove_project(self, project_id: str):
        """Remove a project ID from the user's projects list"""
        if project_id in self.projects:
            self.projects.remove(project_id)
            self.update_modify()
            self.save_to_db()

    class Config:
        from_attributes = True
        json_schema_extra = {
            "example": {
                "user_id": "user123",
                "username": "johndoe",
                "email": "john.doe@example.com",
                "first_name": "John",
                "last_name": "Doe",
                "phone": "+1234567890",
                "profile_pic": "https://example.com/profile.jpg",
                "account_type": "banker",
                "title": "Senior Banker",
                "team_id": "team123",
                "is_active": True,
            }
        }


if __name__ == "__main__":
    user = UserBase(
        user_id="123",
        username="johndoe",
        email="john.doe@example.com",
        first_name="John",
        last_name="Doe",
        phone="+1234567890",
        profile_pic="https://example.com/profile.jpg",
        account_type=AccountType.BANKER,
        signature="signature123",
        title="Senior Banker",
        team_id="123",
    )
    user.update_username("jane_doe")
    user.update_team("456")
    user.update_account_type(AccountType.SELLER)
    user.update_profile(first_name="Jane", title="Lead Seller")
    print(user)
