"""Pydantic schemas for the cPanel Reseller Manager."""
from __future__ import annotations

from datetime import datetime
from decimal import Decimal
from typing import List, Optional

from pydantic import BaseModel, ConfigDict, Field


# ---------------------------------------------------------------------------
# Servers
# ---------------------------------------------------------------------------
class CpanelServerBase(BaseModel):
    name: str = Field(..., max_length=120)
    hostname: str = Field(..., max_length=255)
    port: int = 2087
    username: str = "root"
    verify_tls: bool = True
    is_active: bool = True
    notes: Optional[str] = None


class CpanelServerCreate(CpanelServerBase):
    api_token: str = Field(..., min_length=8, description="WHM API token (plain text; stored encrypted).")


class CpanelServerUpdate(BaseModel):
    name: Optional[str] = None
    hostname: Optional[str] = None
    port: Optional[int] = None
    username: Optional[str] = None
    verify_tls: Optional[bool] = None
    is_active: Optional[bool] = None
    notes: Optional[str] = None
    api_token: Optional[str] = None  # optional; only update when present


class CpanelServerOut(CpanelServerBase):
    model_config = ConfigDict(from_attributes=True)

    id: int
    last_tested_at: Optional[datetime] = None
    last_test_status: Optional[str] = None
    last_test_message: Optional[str] = None
    created_at: datetime
    updated_at: datetime


class CpanelServerTestResult(BaseModel):
    ok: bool
    message: str
    whm_version: Optional[str] = None


# ---------------------------------------------------------------------------
# Packages
# ---------------------------------------------------------------------------
class CpanelPackageBase(BaseModel):
    server_id: int
    display_name: str
    slug: str
    description: Optional[str] = None
    monthly_price: Decimal = Decimal("0")
    currency: str = "USD"
    whmcs_product_id: Optional[int] = None
    whm_package_name: str

    disk_quota_mb: Optional[int] = None
    bandwidth_mb: Optional[int] = None
    max_email_accounts: Optional[int] = None
    max_ftp_accounts: Optional[int] = None
    max_databases: Optional[int] = None
    max_subdomains: Optional[int] = None
    max_addon_domains: Optional[int] = None
    max_parked_domains: Optional[int] = None

    has_ssl: bool = True
    has_backup: bool = True
    has_ssh: bool = False
    has_wordpress_tools: bool = True
    has_cloudlinux: bool = False

    cpu_limit_percent: Optional[int] = None
    memory_limit_mb: Optional[int] = None
    io_limit_kbps: Optional[int] = None
    iops_limit: Optional[int] = None
    ep_limit: Optional[int] = None
    nproc_limit: Optional[int] = None

    is_active: bool = True
    sort_order: int = 0


class CpanelPackageCreate(CpanelPackageBase):
    pass


class CpanelPackageUpdate(BaseModel):
    display_name: Optional[str] = None
    description: Optional[str] = None
    monthly_price: Optional[Decimal] = None
    currency: Optional[str] = None
    whmcs_product_id: Optional[int] = None
    whm_package_name: Optional[str] = None
    disk_quota_mb: Optional[int] = None
    bandwidth_mb: Optional[int] = None
    max_email_accounts: Optional[int] = None
    max_ftp_accounts: Optional[int] = None
    max_databases: Optional[int] = None
    max_subdomains: Optional[int] = None
    max_addon_domains: Optional[int] = None
    max_parked_domains: Optional[int] = None
    has_ssl: Optional[bool] = None
    has_backup: Optional[bool] = None
    has_ssh: Optional[bool] = None
    has_wordpress_tools: Optional[bool] = None
    has_cloudlinux: Optional[bool] = None
    cpu_limit_percent: Optional[int] = None
    memory_limit_mb: Optional[int] = None
    io_limit_kbps: Optional[int] = None
    iops_limit: Optional[int] = None
    ep_limit: Optional[int] = None
    nproc_limit: Optional[int] = None
    is_active: Optional[bool] = None
    sort_order: Optional[int] = None


class CpanelPackageOut(CpanelPackageBase):
    model_config = ConfigDict(from_attributes=True)

    id: int
    created_at: datetime
    updated_at: datetime


# ---------------------------------------------------------------------------
# Accounts
# ---------------------------------------------------------------------------
class CpanelAccountAdminCreate(BaseModel):
    user_id: str
    server_id: int
    package_id: int
    main_domain: str
    contact_email: Optional[str] = None
    whmcs_service_id: Optional[int] = None
    whmcs_client_id: Optional[int] = None


class CpanelAccountOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    user_id: str
    server_id: int
    package_id: Optional[int]
    whmcs_service_id: Optional[int]
    whmcs_client_id: Optional[int]
    cpanel_username: str
    main_domain: str
    contact_email: Optional[str]
    status: str
    suspend_reason: Optional[str]
    last_error: Optional[str]
    provisioned_at: Optional[datetime]
    suspended_at: Optional[datetime]
    unsuspended_at: Optional[datetime]
    terminated_at: Optional[datetime]
    created_at: datetime
    updated_at: datetime


class CpanelAccountUsageOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    disk_used_mb: Optional[int] = None
    disk_limit_mb: Optional[int] = None
    bandwidth_used_mb: Optional[int] = None
    bandwidth_limit_mb: Optional[int] = None
    email_accounts: Optional[int] = None
    ftp_accounts: Optional[int] = None
    databases: Optional[int] = None
    subdomains: Optional[int] = None
    addon_domains: Optional[int] = None
    ssl_status: Optional[str] = None
    backup_status: Optional[str] = None
    cpu_used_percent: Optional[int] = None
    memory_used_mb: Optional[int] = None
    entry_processes: Optional[int] = None
    last_synced_at: Optional[datetime] = None


class CpanelAccountDetail(CpanelAccountOut):
    server_hostname: Optional[str] = None
    package_name: Optional[str] = None
    usage: Optional[CpanelAccountUsageOut] = None


class CpanelAccountActionResult(BaseModel):
    ok: bool
    message: str
    account: Optional[CpanelAccountOut] = None


class CpanelChangePackageIn(BaseModel):
    new_package_id: int


class CpanelSsoResult(BaseModel):
    url: str
    expires_in_seconds: int = 300


# ---------------------------------------------------------------------------
# Quick actions (client area) — input/output shapes
# ---------------------------------------------------------------------------
class EmailAccountIn(BaseModel):
    email: str = Field(..., description="Full email address: user@domain")
    password: str = Field(..., min_length=8)
    quota_mb: int = 250


class FtpAccountIn(BaseModel):
    username: str
    password: str = Field(..., min_length=8)
    quota_mb: int = 0  # 0 = unlimited
    homedir: Optional[str] = None


class MysqlDatabaseIn(BaseModel):
    db_name: str


class MysqlUserIn(BaseModel):
    username: str
    password: str = Field(..., min_length=8)


class SubdomainIn(BaseModel):
    subdomain: str
    parent_domain: str
    docroot: Optional[str] = None


class SimpleItemOut(BaseModel):
    name: str
    extra: Optional[str] = None


class QuickActionResult(BaseModel):
    ok: bool
    message: str


# ---------------------------------------------------------------------------
# API logs & audit
# ---------------------------------------------------------------------------
class CpanelApiLogOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    server_id: Optional[int]
    account_id: Optional[int]
    endpoint: str
    method: str
    status: str
    http_status: Optional[int]
    duration_ms: Optional[int]
    request_preview: Optional[str]
    response_preview: Optional[str]
    error_message: Optional[str]
    created_at: datetime


class CpanelAuditLogOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    action: str
    admin_user_id: Optional[str]
    admin_email: Optional[str]
    account_id: Optional[int]
    target_user_id: Optional[str]
    details: Optional[str]
    created_at: datetime


# ---------------------------------------------------------------------------
# Orphan detection
# ---------------------------------------------------------------------------
class CpanelOrphanAccount(BaseModel):
    cpanel_username: str
    main_domain: str
    package: Optional[str] = None
    server_id: int


class CpanelOrphanLinkIn(BaseModel):
    user_id: str
    server_id: int
    cpanel_username: str
    main_domain: str
    package_id: Optional[int] = None
    whmcs_service_id: Optional[int] = None
    whmcs_client_id: Optional[int] = None


# ---------------------------------------------------------------------------
# Package sync output
# ---------------------------------------------------------------------------
class CpanelPackageSyncResult(BaseModel):
    ok: bool
    imported: int = 0
    updated: int = 0
    items: List[str] = []
    message: Optional[str] = None