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


class CreateTenantRequest(BaseModel):
    organization_name: str
    subdomain: str
    cemetery_type: Optional[str] = None
    contact_email: EmailStr
    contact_phone: Optional[str] = None
    address: Optional[str] = None
    plan: str = "starter"
    admin_first_name: str
    admin_last_name: str
    admin_password: str

    @field_validator("subdomain")
    @classmethod
    def validate_subdomain(cls, v: str) -> str:
        v = v.lower().strip()
        if not re.match(r'^[a-z0-9][a-z0-9-]{1,60}[a-z0-9]$', v):
            raise ValueError("Subdomain must be 3-62 lowercase alphanumeric chars or hyphens")
        reserved = ["www", "admin", "api", "mail", "smtp", "indelis", "support"]
        if v in reserved:
            raise ValueError(f"'{v}' is a reserved subdomain")
        return v


class UpdateTenantRequest(BaseModel):
    organization_name: Optional[str] = None
    cemetery_type: Optional[str] = None
    contact_name: Optional[str] = None
    contact_email: Optional[EmailStr] = None
    contact_phone: Optional[str] = None
    address: Optional[str] = None
    status: Optional[str] = None
    plan: Optional[str] = None
    # Signup management fields
    size: Optional[str] = None
    account_manager: Optional[str] = None
    feature_flags: Optional[dict] = None
    credentials_sent_at: Optional[str] = None


class AdminCreateTenantRequest(BaseModel):
    """Schema for site-admin creating an account on behalf of a customer."""
    organization_name: str = Field(..., min_length=2)
    cemetery_type: Optional[str] = None
    contact_name: str = Field(..., min_length=1)
    contact_email: EmailStr
    contact_phone: Optional[str] = None
    size: Optional[str] = None
    plan: str = Field("professional")
    signup_source: str = Field("admin")
    first_payment: Optional[dict] = None

    @field_validator("plan")
    @classmethod
    def validate_plan(cls, v: str) -> str:
        valid = {"starter", "professional", "enterprise"}
        if v not in valid:
            raise ValueError(f"Plan must be one of: {', '.join(sorted(valid))}")
        return v


class SendCredentialsRequest(BaseModel):
    credentials_sent_at: str  # ISO datetime string


class PublicSignupRequest(BaseModel):
    """Schema for the public self-service cemetery signup form.

    Fields match the React SignUpPage exactly. Subdomain is auto-derived
    server-side from organization_name — clients must NOT supply it.
    """

    organization_name: str = Field(..., min_length=2, description="Cemetery / organization name")
    name: str = Field(..., min_length=1, description="Full name of the administrator")
    email: EmailStr = Field(..., description="Work email address")
    phone: Optional[str] = Field(None, description="Contact phone (optional)")
    cemetery_type: str = Field(..., min_length=1, description="Type of cemetery")
    size: Optional[str] = Field(None, description="Approximate plot count range (optional)")
    plan: str = Field("professional", description="Subscription plan")

    @field_validator("organization_name")
    @classmethod
    def strip_html_org(cls, v: str) -> str:
        v = re.sub(r"<[^>]+>", "", v).strip()
        if len(v) < 2:
            raise ValueError("Organization name must be at least 2 characters")
        return v

    @field_validator("name")
    @classmethod
    def strip_html_name(cls, v: str) -> str:
        return re.sub(r"<[^>]+>", "", v).strip()

    @field_validator("plan")
    @classmethod
    def validate_plan(cls, v: str) -> str:
        valid = {"starter", "professional", "enterprise"}
        if v not in valid:
            raise ValueError(f"Plan must be one of: {', '.join(sorted(valid))}")
        return v


class UpdateBrandingRequest(BaseModel):
    public_site_name: Optional[str] = None
    location_tagline: Optional[str] = None
    accent_color: Optional[str] = None
    logo_url: Optional[str] = None
    favicon_url: Optional[str] = None
    custom_css: Optional[str] = None
