from pydantic import BaseModel, ConfigDict, EmailStr, Field,field_validator, root_validator
from typing import List
from datetime import datetime
from src.constants import CompanyPlanEnum,CompanyUserRoleEnum,DepartmentEnum,ApplicationUserRoleEnum
import re

class CompanyUserLogin(BaseModel): # for login
    email: EmailStr = Field(..., example="srikanth.m@mavengroup.in")
    password: str = Field(..., example="User@123")


class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"



class CompanyUserRestPassword(BaseModel):

    new_password: str = Field(..., min_length=8, max_length=15)

    @field_validator('new_password')
    @classmethod
    def validate_password(cls, value: str) -> str:
        if not re.search(r'[A-Z]', value):
            raise ValueError('Password must contain at least one uppercase letter')
        if not re.search(r'[a-z]', value):
            raise ValueError('Password must contain at least one lowercase letter')
        if not re.search(r'[!@#$%^&*(),.?":{}|<>_\-+=]', value):
            raise ValueError('Password must contain at least one special character')
        if not re.search(r'\d', value):  # optional: require digits
            raise ValueError('Password must contain at least one digit')
        return value


class CompanyUserPasswordResetRequest(BaseModel):
    email: EmailStr
class CompanyUserCreate(BaseModel):
    full_name: str
    user_email: EmailStr
    user_department: DepartmentEnum
    user_role: CompanyUserRoleEnum 


class AddUser(BaseModel):
    full_name: str
    user_email: EmailStr
    user_department: DepartmentEnum
    user_role: CompanyUserRoleEnum







class CompanyRegistration(BaseModel):
    company_name: str = Field(..., max_length=100)
    legal_name: str = Field(None, max_length=150)
    bio: str = Field(None, max_length=255)
    address: str = Field(None, max_length=255)
    home_country: str = Field(None, max_length=50)
    company_logo_url: str = Field(None, max_length=555)
    has_branches: bool = False
    company_email: EmailStr
    company_phone_number: str = Field(None, max_length=255)
    plan: CompanyPlanEnum = CompanyPlanEnum.BASIC

    users: List[CompanyUserCreate]



class CompanyRegistrationResponse(BaseModel):
    company_name: str 
    legal_name: str 
    bio: str 
    address: str 
    home_country: str 
    company_logo_url: str 
    has_branches: bool 
    email: EmailStr
    phone_number: str
    plan: CompanyPlanEnum
    
    class Config:
        from_attributes = True



class UserCreationResponse(BaseModel):
    company: CompanyRegistrationResponse  # define separately
    users: List[CompanyUserCreate]



#Application user schemas
class CreateAppUserRequest(BaseModel):
    email: EmailStr
    password: str = Field(min_length=8)
    full_name: str
    role: ApplicationUserRoleEnum
    is_2FA_required: bool = False

class CreateAppUserResponse(BaseModel):
    email: EmailStr
    full_name: str
    role: ApplicationUserRoleEnum
    is_account_active: bool
    is_2FA_required: bool
    is_2FA_enabled: bool
    created_at: datetime

    class Config:
        from_attributes = True

class AppuserLoginRequest(BaseModel):
    email: EmailStr = Field(..., example="venu123@gmail.com")
    password: str = Field(..., example="User@123")
class PlanCurrentCompanyUser(BaseModel):
    sub: str
    email: str
    plan: CompanyPlanEnum


from pydantic import BaseModel
from typing import Optional
from datetime import date
from src.models.company import BillingCycle, BlogStatusEnum

# ---------- Department Schemas ----------
class DepartmentBase(BaseModel):
    name: str
    description: Optional[str]

class DepartmentCreate(DepartmentBase):
    pass

class DepartmentUpdate(BaseModel):
    name: Optional[str]
    description: Optional[str]

class DepartmentResponse(DepartmentBase):
    id: int
    class Config:
        orm_mode = True

# ---------- Role Schemas ----------
class RoleBase(BaseModel):
    name: str
    description: Optional[str]

class RoleCreate(RoleBase):
    pass

class RoleUpdate(BaseModel):
    name: Optional[str]
    description: Optional[str]

class RoleResponse(RoleBase):
    id: int
    class Config:
        orm_mode = True

# ---------- RoleDepartment Schemas ----------
class RoleDepartmentBase(BaseModel):
    role_id: int
    department_id: int

class RoleDepartmentCreate(RoleDepartmentBase):
    pass

class RoleDepartmentUpdate(BaseModel):
    role_id: Optional[int]
    department_id: Optional[int]

class RoleDepartmentResponse(RoleDepartmentBase):
    id: int
    class Config:
        orm_mode = True

# ---------- Module Schemas ----------
class ModuleBase(BaseModel):
    name: str
    description: Optional[str]

class ModuleCreate(ModuleBase):
    pass

class ModuleUpdate(BaseModel):
    name: Optional[str]
    description: Optional[str]

class ModuleResponse(ModuleBase):
    id: int
    class Config:
        orm_mode = True

# ---------- SubscriptionPlan Schemas ----------
class SubscriptionPlanBase(BaseModel):
    name: str
    billing_cycle: BillingCycle
    price: float

class SubscriptionPlanCreate(SubscriptionPlanBase):
    pass

class SubscriptionPlanUpdate(BaseModel):
    name: Optional[str]
    billing_cycle: Optional[BillingCycle]
    price: Optional[float]

class SubscriptionPlanResponse(SubscriptionPlanBase):
    id: int
    class Config:
        orm_mode = True

# ---------- Permission Schemas ----------
class PermissionBase(BaseModel):
    name: str
    module_id: int
    description: Optional[str]

class PermissionCreate(PermissionBase):
    pass

class PermissionUpdate(BaseModel):
    name: Optional[str]
    module_id: Optional[int]
    description: Optional[str]

class PermissionResponse(PermissionBase):
    id: int
    class Config:
        orm_mode = True

# ---------- UserRole Schemas ----------
class UserRoleBase(BaseModel):
    user_id: str
    role_department_id: int
    company_id: str

class UserRoleCreate(UserRoleBase):
    pass

class UserRoleUpdate(BaseModel):
    user_id: Optional[str]
    role_department_id: Optional[int]
    company_id: Optional[str]

class UserRoleResponse(UserRoleBase):
    id: int
    class Config:
        orm_mode = True

# ---------- Subscription Schemas ----------
class SubscriptionBase(BaseModel):
    company_id: str
    subscription_plan_id: int
    start_date: date
    end_date: Optional[date]
    status: Optional[str]

class SubscriptionCreate(SubscriptionBase):
    pass

class SubscriptionUpdate(BaseModel):
    company_id: Optional[str]
    plan_id: Optional[int]
    start_date: Optional[date]
    end_date: Optional[date]
    status: Optional[str]

class SubscriptionResponse(SubscriptionBase):
    id: int
    class Config:
        orm_mode = True
from pydantic import BaseModel
from typing import Optional

class ModuleSchema(BaseModel):
    id:int
    name: str
    

    class Config:
        from_attributes = True  # Use this for Pydantic v2 instead of orm_mode
# schemas/subscription_plan.py

from typing import List, Optional
from pydantic import BaseModel
  # adjust path to your enum

class SubscriptionPlanCreate(BaseModel):
    name: str
    collabrator:int
    bussiness_user:int
    view_only:int
    user_limit:int
    price: Optional[str]
    modules: List[ModuleSchema]
class UpdateSubscriptionPlanCreate(BaseModel):
    name: str
    billing_cycle: Optional[BillingCycle]
    collabrator:int
    bussiness_user:int
    view_only:int
    price: Optional[float]
    modules: List[ModuleSchema]
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import date, datetime

class ModuleSchema(BaseModel):
    id: int
    
   

    class Config:
        orm_mode = True

class SubscriptionPlanResponse(BaseModel):
    subscrition_plain_id: int = Field(..., alias="id")  # maps `id` from SQLAlchemy
    name: str
    description: Optional[str]=None
    billing_cycle: str  # or use an Enum if applicable
    price: float
    modules: List[ModuleSchema]

    # ✅ Newly added fields
    collaborators: int
    business_users: int
    view_only: int

    
    class Config:
        orm_mode = True
       

  


  # Pydantic model for incoming request
class DemoBookingRequest(BaseModel):
    name: str
    company: str
    email: EmailStr
    interests: Optional[str] = Field(default="")
    message: str
class InquiryRequest(BaseModel):
    email: EmailStr
    phone: Optional[str] = None
    company: Optional[str] = None
    additional_message: Optional[str] = None
    subscription_plan_id: int  # Foreign key

from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime


class BlogCreate(BaseModel):
    title: str = Field(..., example="My First Blog Post")
    content: str = Field(..., example="This is the body of the blog post.")
    author: str = Field(..., example="John Doe")
    status: BlogStatusEnum = Field(default=BlogStatusEnum.DRAFT, example="draft")
    image: Optional[str]= Field(None, example="")  # New image field
    tags: Optional[List[str]|str] = Field(default_factory=list, example=["fastapi", "python"]) # Default status
    meta_title : Optional[str] = Field(...)
    meta_description : Optional[str] = Field(...)
    alt_text :Optional[str] = Field(...)

class BlogUpdate(BaseModel):
    title: Optional[str]
    content: Optional[str]
    author: Optional[str]
    status: Optional[BlogStatusEnum]
    tags: Optional[List[str] | str]
    image: Optional[str]
    meta_title : Optional[str]
    meta_description :Optional[str]
    alt_text :Optional[str]

    class Config:
        orm_mode = True



# Adjust the path as needed

class BlogOut(BaseModel): 
    id: int
    title: str
    content: str
    author: str
    image: Optional[str]  # New image field
    status: BlogStatusEnum  # ✅ now this works!
    tags: Optional[List[str]|str]
    created_at: datetime
    updated_at: datetime
    
    model_config = ConfigDict(
        from_attributes=True,
       
    )
    meta_title : Optional[str]   #new field added
    meta_description : Optional[str] # new field added
    alt_text : Optional[str]



class PaginatedBlogResponse(BaseModel):
    data: List[BlogOut]
    total: int
    current_page: int
    total_pages: int
    has_next: bool
    limit: int
    offset: int