import re
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional
from uuid import UUID

from pydantic import BaseModel, EmailStr, Field, validator

from utils.dynamo_db import DynamoDB


class Theme(BaseModel):
    heading_font: Optional[str] = None
    text_font: Optional[str] = None
    heading_size: Optional[str] = None
    text_size: Optional[str] = None
    logo_background: Optional[str] = None
    brand_colors: Optional[List[str]] = None
    brand_fonts: Optional[List[dict]] = None


class Owner(BaseModel):
    name: str
    ownership_percentage: float = Field(ge=0, le=100)
    role: Optional[str] = None


class TeamMember(BaseModel):
    user_id: str
    created_at: datetime = Field(default_factory=lambda: datetime.now())
    updated_at: datetime = Field(default_factory=lambda: datetime.now())
    notes: str = ""
    created_by: str = ""

    def model_dump(self, *args, **kwargs):
        """Override model_dump to convert datetime to string"""
        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")
        return data

    class Config:
        json_encoders = {datetime: lambda v: v.isoformat()}


class Team(BaseModel):
    id: str
    name: str
    company_name: str
    company_url: Optional[str] = None
    is_franchise: bool
    description: Optional[str] = None
    logo_url: Optional[str] = None
    theme: Optional[Theme] = None
    owners: List[Owner] = []
    members: List[str] = Field(default_factory=list)
    created_by: str
    created_at: datetime = Field(default_factory=lambda: datetime.now())
    updated_at: datetime = Field(default_factory=lambda: datetime.now())
    stripe_customer_id: Optional[str] = None
    client_config: Optional[dict] = None
    # TODO: Add notes section here

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

    def update_company_info(
        self,
        name: Optional[str] = None,
        company_name: Optional[str] = None,
        company_url: Optional[str] = None,
        description: Optional[str] = None,
    ):
        """Update company information"""
        if name is not None:
            self.name = name
        if company_name is not None:
            self.company_name = company_name
        if company_url is not None:
            self.company_url = company_url
        if description is not None:
            self.description = description
        self.update_modify()

    def update_branding(
        self, logo_url: Optional[str] = None, theme: Optional[Theme] = None
    ):
        """Update team branding"""
        if logo_url is not None:
            self.logo_url = logo_url
        if theme is not None:
            self.theme = theme
        self.update_modify()

    def add_owner(self, owner: Owner):
        """Add a new owner to the team"""
        self.owners.append(owner)
        self.update_modify()

    def remove_owner(self, owner_name: str):
        """Remove an owner from the team"""
        self.owners = [o for o in self.owners if o.name != owner_name]
        self.update_modify()

    def add_member(self, user_id: str):
        """Add a new team member"""
        if user_id not in self.members:
            self.members.append(user_id)
            self.update_modify()

    def remove_member(self, user_id: str):
        """Remove a team member"""
        if user_id in self.members:
            self.members.remove(user_id)
            self.update_modify()

    def update_member_role(self, user_id: str, role: str):
        """This method should be removed or moved elsewhere since we no longer store member details"""
        pass

    def model_dump(self, *args, **kwargs):
        """Override model_dump to handle datetime serialization"""
        data = super().model_dump(*args, **kwargs)
        # Convert created_at and updated_at to ISO format strings
        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")

        # Convert UUID to string
        if data.get("id"):
            data["id"] = str(data["id"])
        return data

    def save_to_db(self):
        """Save team to DynamoDB"""
        db = DynamoDB()
        self.update_modify()
        # Convert to dict and ensure all nested objects are serialized
        data = self.model_dump(exclude_unset=True, mode="json")
        return db.upload_to_dynamodb(db.dynamodb.Table("Team"), data)

    @staticmethod
    def get_company_info(team_id):
        "Get company info from the database"
        db = DynamoDB()
        company_info_data = db.get_item(db.company_info_table, team_id)
        return company_info_data

    @staticmethod
    def get_team_by_id(team_id):
        "Get team by id"
        db = DynamoDB()
        team_data = db.get_item(db.dynamodb.Table("Team"), team_id)
        return team_data

    class Config:
        json_encoders = {datetime: lambda v: v.isoformat(), UUID: lambda v: str(v)}


class CreateUserRequest(BaseModel):
    email: EmailStr
    first_name: str
    last_name: str
    role: str


if __name__ == "__main__":
    team = Team(
        id="123",
        name="Test Team",
        company_name="Test Company",
        company_url="https://www.testcompany.com",
        is_franchise=False,
        description="Test description",
        logo_url="https://www.testcompany.com/logo.png",
        theme=Theme(
            brand_colors=["#000000", "#FFFFFF"], brand_fonts=["Arial", "Helvetica"]
        ),
        owners=[
            Owner(name="John Doe", ownership_percentage=50, role="CEO"),
            Owner(name="Jane Doe", ownership_percentage=50, role="CTO"),
        ],
        created_by="123",
        members=["123", "456"],
        created_at=datetime.now(),
        updated_at=datetime.now(),
    )
    print(team)
