from pydantic import BaseModel, Field, field_validator, EmailStr
from typing import Optional, Dict
import re

_HEX_COLOR_RE = re.compile(r'^#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?$')
_URL_RE = re.compile(r'^https?://')


class BrandingResponse(BaseModel):
    Logo: Dict[str, str]
    Colors: Dict[str, str]
    business_urls: Dict[str, str] = Field(alias="Business URLs")

    class Config:
        populate_by_name = True


class BrandingUpdateRequest(BaseModel):
    primary_color: Optional[str] = Field(None, max_length=7)
    secondary_color: Optional[str] = Field(None, max_length=7)
    accent_color: Optional[str] = Field(None, max_length=7)
    website_url: Optional[str] = Field(None, max_length=2048)
    support_email: Optional[EmailStr] = None
    support_phone: Optional[str] = Field(None, max_length=30)
    show_website_url: Optional[bool] = None
    show_support_email: Optional[bool] = None
    show_support_phone: Optional[bool] = None

    @field_validator("primary_color", "secondary_color", "accent_color", mode="before")
    @classmethod
    def validate_hex_color(cls, v: Optional[str]) -> Optional[str]:
        if v is None:
            return v
        if not _HEX_COLOR_RE.match(v):
            raise ValueError("Color must be a valid hex value (e.g. #28B4ED).")
        return v

    @field_validator("website_url", mode="before")
    @classmethod
    def validate_website_url(cls, v: Optional[str]) -> Optional[str]:
        if v is None or v == "":
            return v
        if not _URL_RE.match(v):
            raise ValueError("website_url must start with http:// or https://.")
        return v

    @field_validator("support_phone", mode="before")
    @classmethod
    def validate_phone(cls, v: Optional[str]) -> Optional[str]:
        if v is None or v == "":
            return v
        # Allow digits, spaces, hyphens, parentheses, and leading +
        if not re.match(r'^[+\d\s\-(). ]{1,30}$', v):
            raise ValueError("support_phone contains invalid characters.")
        return v


class LogoUploadResponse(BaseModel):
    logo_url: str
