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


class LicenseValidateRequest(BaseModel):
    license_key: str = Field(..., min_length=10, max_length=64)
    deployment: str = Field("cloud", description="cloud | local")


class LicenseValidateResponse(BaseModel):
    valid: bool
    message: Optional[str] = None
    license_id: Optional[str] = None
    plan: Optional[str] = None
    deployment_mode: Optional[str] = None
    valid_from: Optional[str] = None
    valid_until: Optional[str] = None
    days_remaining: Optional[int] = None
    max_users: Optional[int] = None
    max_branches: Optional[int] = None
    key_prefix: Optional[str] = None
    status: Optional[str] = None
    setup_token: Optional[str] = None


class LicenseVerifySetupRequest(BaseModel):
    license_key: str = Field(..., min_length=10, max_length=64)
    setup_token: str = Field(..., min_length=20)
    deployment: str = Field("cloud")


class LicenseVerifySetupResponse(BaseModel):
    valid: bool
    message: Optional[str] = None


class LicenseClaimSetupRequest(BaseModel):
    license_key: str = Field(..., min_length=10, max_length=64)
    setup_token: str = Field(..., min_length=20)
    deployment: str = Field("local")
    site_name: Optional[str] = None


class LicenseClaimSetupResponse(BaseModel):
    success: bool
    message: Optional[str] = None


class CloudMirrorProvisionRequest(BaseModel):
    """Local server → cloud hub: create matching tenant (same IDs + admin password hash)."""
    license_key: str = Field(..., min_length=10, max_length=64)
    setup_token: Optional[str] = Field(None, min_length=20)
    mirror_provision_token: Optional[str] = Field(None, min_length=20)
    deployment: str = Field("local")
    company_id: str
    company_code: str
    company_name: str
    admin_user_id: str
    admin_username: str
    admin_password_digest: str
    hq_branch_id: str
    hq_branch_code: str
    legal_name: Optional[str] = None
    admin_email: Optional[str] = None
    admin_first_name: Optional[str] = None
    admin_last_name: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    industry: Optional[str] = None
    currency: str = "BWP"
    country: str = "Botswana"
    timezone: str = "Africa/Gaborone"
    accounting_codes: List[dict] = Field(default_factory=list)
    site_name: Optional[str] = None


class CloudMirrorProvisionResponse(BaseModel):
    success: bool
    message: Optional[str] = None
    company_id: Optional[str] = None
    company_code: Optional[str] = None
    cloud_login_url: Optional[str] = None


class LicenseIssueRequest(BaseModel):
    plan: str = "standard"
    years: int = Field(1, ge=1, le=10)
    deployment_mode: str = Field("both", description="cloud | local | both")
    customer_name: Optional[str] = None
    customer_email: Optional[str] = None
    max_users: int = Field(25, ge=1, le=500)
    max_branches: int = Field(1, ge=1, le=500, description="Total branches incl. head office")
    notes: Optional[str] = None


class LicenseIssueResponse(BaseModel):
    license_id: str
    license_key: str
    key_prefix: str
    valid_until: datetime
    plan: str
    message: str


class LicenseRenewRequest(BaseModel):
    years: int = Field(1, ge=1, le=10)


class LicenseUpgradeRequest(BaseModel):
    """Raise limits and/or extend validity on an existing main license."""
    max_branches: Optional[int] = Field(None, ge=1, le=500)
    max_users: Optional[int] = Field(None, ge=1, le=500)
    add_years: int = Field(0, ge=0, le=10)


class LicenseKeySummary(BaseModel):
    id: str
    key_prefix: str
    plan: str
    status: str
    deployment_mode: str
    valid_from: datetime
    valid_until: datetime
    company_id: Optional[str] = None
    customer_name: Optional[str] = None
    customer_email: Optional[str] = None
    renewals_count: int = 0

    class Config:
        from_attributes = True


class LicenseStatusResponse(BaseModel):
    licensed: bool
    status: Optional[str] = None
    message: Optional[str] = None
    plan: Optional[str] = None
    valid_until: Optional[str] = None
    days_remaining: Optional[int] = None
    deployment_mode: Optional[str] = None
    key_prefix: Optional[str] = None
    enforcement: Optional[bool] = None


class NodeRegisterRequest(BaseModel):
    license_key: str
    node_name: str = Field(..., min_length=2, max_length=255)
    public_base_url: Optional[str] = None
    machine_fingerprint: Optional[str] = None
    app_version: Optional[str] = None


class NodeRegisterResponse(BaseModel):
    node_id: str
    sync_token: str
    company_id: Optional[str] = None
    message: str


class NodeHeartbeatRequest(BaseModel):
    node_id: str
    sync_token: str
    app_version: Optional[str] = None
