from pydantic import BaseModel, EmailStr, Field, ConfigDict
from typing import Optional, List
from datetime import datetime

# Response models
class MaterialBase(BaseModel):
    id: int
    name_en: Optional[str] = None
    name_ru: Optional[str] = None
    name_ua: Optional[str] = None
    name_me: Optional[str] = None
    desc_en: Optional[str] = None
    desc_ru: Optional[str] = None
    desc_ua: Optional[str] = None
    desc_me: Optional[str] = None
    long_desc_en: Optional[str] = None
    long_desc_ru: Optional[str] = None
    long_desc_ua: Optional[str] = None
    long_desc_me: Optional[str] = None
    service_id: Optional[int] = None
    price_per_cm3: float
    price_per_hour: Optional[float] = None
    speed_coeff: Optional[float] = 1.0
    available_colors: Optional[List[str]] = None
    is_active: bool

class ServiceBase(BaseModel):
    id: int
    name_en: Optional[str] = None
    name_ru: Optional[str] = None
    name_ua: Optional[str] = None
    name_me: Optional[str] = None
    desc_en: Optional[str] = None
    desc_ru: Optional[str] = None
    desc_ua: Optional[str] = None
    desc_me: Optional[str] = None
    tech_type: Optional[str] = None
    price_per_hour: Optional[float] = None
    is_active: bool

# Management models
class MaterialCreate(BaseModel):
    name_en: str
    name_ru: str
    name_ua: str
    name_me: str
    desc_en: str
    desc_ru: str
    desc_ua: str
    desc_me: str
    long_desc_en: Optional[str] = ""
    long_desc_ru: Optional[str] = ""
    long_desc_ua: Optional[str] = ""
    long_desc_me: Optional[str] = ""
    service_id: Optional[int] = None
    price_per_cm3: float
    price_per_hour: Optional[float] = 0.0
    speed_coeff: Optional[float] = 1.0
    available_colors: Optional[List[str]] = None
    is_active: bool = True

class MaterialUpdate(BaseModel):
    name_en: Optional[str] = None
    name_ru: Optional[str] = None
    name_ua: Optional[str] = None
    name_me: Optional[str] = None
    desc_en: Optional[str] = None
    desc_ru: Optional[str] = None
    desc_ua: Optional[str] = None
    desc_me: Optional[str] = None
    long_desc_en: Optional[str] = None
    long_desc_ru: Optional[str] = None
    long_desc_ua: Optional[str] = None
    long_desc_me: Optional[str] = None
    price_per_cm3: Optional[float] = None
    price_per_hour: Optional[float] = None
    speed_coeff: Optional[float] = None
    service_id: Optional[int] = None
    available_colors: Optional[List[str]] = None
    is_active: Optional[bool] = None

class ServiceCreate(BaseModel):
    name_en: str
    name_ru: str
    name_ua: str
    name_me: str
    desc_en: str
    desc_ru: str
    desc_ua: str
    desc_me: str
    tech_type: Optional[str] = None
    price_per_hour: Optional[float] = 0.0
    is_active: bool = True

class ServiceUpdate(BaseModel):
    name_en: Optional[str] = None
    name_ru: Optional[str] = None
    name_ua: Optional[str] = None
    name_me: Optional[str] = None
    desc_en: Optional[str] = None
    desc_ru: Optional[str] = None
    desc_ua: Optional[str] = None
    desc_me: Optional[str] = None
    tech_type: Optional[str] = None
    price_per_hour: Optional[float] = None
    is_active: Optional[bool] = None

# Order creation models
class OrderFileBase(BaseModel):
    filename: str
    file_size: Optional[int]

class OrderCreate(BaseModel):
    first_name: str = Field(..., min_length=1)
    last_name: str = Field(..., min_length=1)
    phone: str = Field(..., min_length=5)
    email: EmailStr
    shipping_address: str = Field(..., min_length=10)
    model_link: Optional[str] = None
    quantity: int = Field(1, ge=1)
    notes: Optional[str] = None
    material_id: int
    color_name: Optional[str] = None

# User models
class UserCreate(BaseModel):
    email: EmailStr
    password: str = Field(..., min_length=6)
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    phone: Optional[str] = None
    shipping_address: Optional[str] = None
    preferred_language: Optional[str] = "en"
    is_company: bool = False
    company_name: Optional[str] = None
    company_pib: Optional[str] = None
    company_address: Optional[str] = None

class UserUpdate(BaseModel):
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    phone: Optional[str] = None
    shipping_address: Optional[str] = None
    preferred_language: Optional[str] = None
    can_chat: Optional[bool] = None
    is_active: Optional[bool] = None
    is_company: Optional[bool] = None
    company_name: Optional[str] = None
    company_pib: Optional[str] = None
    company_address: Optional[str] = None

class AdminUserUpdate(UserUpdate):
    role: Optional[str] = None
    password: Optional[str] = Field(None, min_length=6)

class UserLogin(BaseModel):
    email: EmailStr
    password: str
    captcha_token: Optional[str] = None

class UserResponse(BaseModel):
    id: int
    email: EmailStr
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    phone: Optional[str] = None
    shipping_address: Optional[str] = None
    preferred_language: str = "en"
    role: str
    can_chat: bool
    is_active: bool
    is_company: bool
    company_name: Optional[str] = None
    company_pib: Optional[str] = None
    company_address: Optional[str] = None
    ip_address: Optional[str] = None
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)

class AdminOrderUpdate(BaseModel):
    status: Optional[str] = None
    total_price: Optional[float] = None
    material_id: Optional[int] = None
    material_name: Optional[str] = None
    color_name: Optional[str] = None
    quantity: Optional[int] = None
    send_notification: Optional[bool] = False
    fiscal_qr_url: Optional[str] = None
    ikof: Optional[str] = None
    jikr: Optional[str] = None
    # Customer data
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    email: Optional[EmailStr] = None
    phone: Optional[str] = None
    shipping_address: Optional[str] = None
    notes: Optional[str] = None
    # Review management
    review_text: Optional[str] = None
    rating: Optional[int] = None
    review_approved: Optional[bool] = None

class EstimateRequest(BaseModel):
    material_id: int
    file_sizes: List[int] # in bytes
    file_quantities: Optional[List[int]] = None
    # Possible to add density or other params later

class Token(BaseModel):
    access_token: str
    token_type: str

from typing import Optional, List, Any

class SocialLogin(BaseModel):
    provider: str # 'google'
    token: str
    email: Any = None
    first_name: Any = None
    last_name: Any = None
    preferred_language: Any = "en"

class ForgotPassword(BaseModel):
    email: EmailStr

class ResetPassword(BaseModel):
    token: str
    new_password: str = Field(..., min_length=6)

class PhotoUpdate(BaseModel):
    is_public: bool
    caption: Optional[str] = None

class OrderResponse(OrderCreate):
    id: int
    status: str
    total_price: Optional[float] = None
    estimated_price: Optional[float] = None
    material_name: Optional[str] = None
    material_price: Optional[float] = None
    material_id: Optional[int] = None
    color_name: Optional[str] = None
    original_params: Optional[str] = None
    created_at: datetime
    # Review fields
    review_text: Optional[str] = None
    rating: Optional[int] = 0
    review_approved: bool = False
    
    model_config = ConfigDict(from_attributes=True)

class OrderReview(BaseModel):
    rating: int = Field(..., ge=1, le=5)
    review_text: str = Field(..., min_length=2)

class PublicReview(BaseModel):
    first_name: str
    rating: Optional[int] = 0
    review_text: Optional[str] = None

class MessageCreate(BaseModel):
    message: str

class ContactRequest(BaseModel):
    name: str = Field(..., min_length=1)
    email: EmailStr
    subject: str = Field(..., min_length=1)
    message: str = Field(..., min_length=1)

class TokenVerify(BaseModel):
    token: str

# Warehouse models
class WarehouseItemBase(BaseModel):
    material_id: int
    color_name: str
    quantity: float = 0.0 # Total weight
    unit_mass: float = 1.0 # Weight of one unit (e.g. 1kg spool)
    units_count: float = 0.0 # Number of units (e.g. 1.5 spools)
    notes: Optional[str] = None
    is_active: bool = True

class WarehouseItemCreate(WarehouseItemBase):
    pass

class WarehouseItemUpdate(BaseModel):
    material_id: Optional[int] = None
    color_name: Optional[str] = None
    quantity: Optional[float] = None
    unit_mass: Optional[float] = None
    units_count: Optional[float] = None
    notes: Optional[str] = None
    is_active: Optional[bool] = None

class WarehouseItemResponse(WarehouseItemBase):
    id: int
    material_name_en: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)
