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


class CompanyBase(BaseModel):
    name: str = Field(..., min_length=2, max_length=255)
    legal_name: Optional[str] = None
    company_code: Optional[str] = Field(None, max_length=20)
    registration_number: Optional[str] = None
    tax_identification_number: Optional[str] = None
    vat_registration_number: Optional[str] = None
    industry: Optional[str] = None
    # Contact
    address_line1: Optional[str] = None
    address_line2: Optional[str] = None
    city: Optional[str] = None
    state: Optional[str] = None
    country: Optional[str] = "Botswana"
    postal_code: Optional[str] = None
    phone: Optional[str] = None
    phone2: Optional[str] = None
    fax: Optional[str] = None
    email: Optional[str] = None
    website: Optional[str] = None
    # Branding
    logo_url: Optional[str] = None
    primary_color: Optional[str] = "#0d6efd"
    # Financial
    currency: Optional[str] = "BWP"
    default_vat_rate: Optional[float] = 14.0
    fiscal_year_start_month: Optional[int] = Field(1, ge=1, le=12)
    timezone: Optional[str] = "Africa/Gaborone"
    # Document footers
    invoice_footer: Optional[str] = None
    receipt_footer: Optional[str] = None
    po_terms: Optional[str] = None
    subscription_plan: Optional[str] = "standard"

    @field_validator("company_code")
    @classmethod
    def clean_company_code(cls, v):
        if v:
            v = re.sub(r"[^A-Z0-9]", "", v.upper())
            if len(v) < 3:
                raise ValueError("Company code must be at least 3 characters (letters/numbers only)")
        return v


class CompanyCreate(CompanyBase):
    """Used for the registration wizard — also creates the first admin user."""
    # First admin account
    admin_username: str = Field(..., min_length=3, max_length=50)
    admin_password: str = Field(..., min_length=8)
    admin_email: Optional[str] = None
    admin_first_name: Optional[str] = None
    admin_last_name: Optional[str] = None


class CompanyUpdate(CompanyBase):
    name: Optional[str] = None  # Allow partial updates


class CompanyResponse(CompanyBase):
    id: str
    is_active: bool
    is_setup_complete: bool
    setup_completed_at: Optional[datetime] = None
    created_at: Optional[datetime] = None

    class Config:
        from_attributes = True


class CompanyPublicResponse(BaseModel):
    """Minimal info exposed during login (no sensitive fields)."""
    id: str
    name: str
    company_code: str
    logo_url: Optional[str] = None
    currency: Optional[str] = None
    country: Optional[str] = None

    class Config:
        from_attributes = True


class CompanyRegistrationResult(BaseModel):
    company: CompanyResponse
    admin_user_id: str
    admin_username: str
    message: str


# ── Full setup wizard payload ──────────────────────────────────────────────────

class BranchSetup(BaseModel):
    name: str
    code: Optional[str] = None
    address: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    is_head_office: bool = False


class UserSetup(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    password: str = Field(..., min_length=6)
    email: Optional[str] = None
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    role: str = "manager"
    branch_code: Optional[str] = None  # assign to this branch code


class OpeningBalanceEntry(BaseModel):
    account_code: str
    debit: float = 0.0
    credit: float = 0.0
    description: Optional[str] = None


class CompanyFullSetup(CompanyCreate):
    """Complete wizard payload — creates everything in one atomic transaction."""
    license_key: Optional[str] = Field(
        None,
        description="CNP purchase token (CNP-PLAN-YYYY-XXXX-XXXX-XXXX)",
    )
    setup_token: Optional[str] = Field(
        None,
        description="Short-lived token from POST /licensing/validate (required for setup)",
    )
    deployment: Optional[str] = Field(
        "cloud",
        description="cloud = hosted tenant | local = on-premise node",
    )
    # Additional branches beyond HQ (HQ is auto-created from company fields)
    additional_branches: Optional[list[BranchSetup]] = []
    # Additional users beyond the super_admin
    additional_users: Optional[list[UserSetup]] = []
    # Opening balance journal entries
    opening_balances: Optional[list[OpeningBalanceEntry]] = []


class CompanyFullSetupResult(BaseModel):
    company: CompanyResponse
    company_code: str
    admin_username: str
    admin_password_hint: str
    branches_created: int
    users_created: int
    accounts_created: int
    opening_balance_entries: int
    walkin_customer_id: Optional[str] = None
    message: str
    cloud_mirror_success: Optional[bool] = None
    cloud_login_url: Optional[str] = None
    cloud_mirror_message: Optional[str] = None
