from __future__ import annotations

from dataclasses import dataclass, field

WIZARD_STEPS = [
    "general",
    "os",
    "system",
    "disks",
    "cpu",
    "memory",
    "network",
    "confirm",
]


@dataclass
class AuthenticationState:
    username: str | None = None
    realm: str | None = None
    authenticated: bool = False


@dataclass
class GeneralConfig:
    node: str = ""
    vmid: int = 101
    name: str = ""
    pool: str = ""
    tags: list[str] = field(default_factory=list)
    ha_enabled: bool = True
    onboot: bool = False
    startup_order: str = ""
    startup_delay: str = ""
    shutdown_timeout: str = ""


@dataclass
class OsConfig:
    media_choice: str = "iso"
    storage: str = ""
    iso: str = ""
    physical_drive_path: str = "/dev/sr0"
    guest_type: str = "linux"
    guest_version: str = "l26"


@dataclass
class SystemConfig:
    graphic_card: str = "default"
    machine: str = "q35"
    bios: str = "ovmf"
    add_efi_disk: bool = True
    efi_storage: str = "ceph-pool"
    pre_enrolled_keys: bool = False
    scsi_controller: str = "virtio-scsi-single"
    qemu_agent: bool = True
    tpm_enabled: bool = False


@dataclass
class DiskConfig:
    bus: str = "scsi"
    device: int = 0
    storage: str = "ceph-pool"
    size_gib: int = 32
    format: str = "raw"
    cache: str = "none"
    discard: bool = False
    io_thread: bool = True
    ssd_emulation: bool = True
    backup: bool = True
    skip_replication: bool = False
    async_io: str = "io_uring"

    @property
    def slot_name(self) -> str:
        return f"{self.bus}{self.device}"


@dataclass
class CpuConfig:
    cores: int = 2
    sockets: int = 1
    cpu_type: str = "host"


@dataclass
class MemoryConfig:
    memory_mib: int = 2048
    min_memory_mib: int = 2048
    ballooning: bool = True
    allow_ksm: bool = True


@dataclass
class NetworkConfig:
    no_network_device: bool = False
    bridge: str = "vmbr9"
    vlan_tag: str = ""
    model: str = "virtio"
    mac_address: str = ""
    firewall: bool = True
    disconnected: bool = False
    mtu: str = ""
    rate_limit: str = ""
    multiqueue: str = ""


@dataclass
class VmConfig:
    general: GeneralConfig = field(default_factory=GeneralConfig)
    os: OsConfig = field(default_factory=OsConfig)
    system: SystemConfig = field(default_factory=SystemConfig)
    disks: list[DiskConfig] = field(default_factory=lambda: [DiskConfig()])
    cpu: CpuConfig = field(default_factory=CpuConfig)
    memory: MemoryConfig = field(default_factory=MemoryConfig)
    network: NetworkConfig = field(default_factory=NetworkConfig)


@dataclass
class ReferenceData:
    nodes: list[str] = field(default_factory=list)
    pools: list[str] = field(default_factory=list)
    existing_tags: list[str] = field(default_factory=list)
    bridges: list[str] = field(default_factory=list)
    iso_storages: list[str] = field(default_factory=list)
    disk_storages: list[str] = field(default_factory=list)
    all_storages: list[str] = field(default_factory=list)
    isos: list[str] = field(default_factory=list)


@dataclass
class SubmissionState:
    phase: str = "idle"
    message: str = ""
    node: str | None = None
    vmid: int | None = None
    partial_success: bool = False


@dataclass
class WorkflowState:
    current_step_index: int = 0
    available_realms: list[str] = field(default_factory=list)
    authentication: AuthenticationState = field(default_factory=AuthenticationState)
    config: VmConfig = field(default_factory=VmConfig)
    reference_data: ReferenceData = field(default_factory=ReferenceData)
    submission: SubmissionState = field(default_factory=SubmissionState)

    @property
    def current_step(self) -> str:
        return WIZARD_STEPS[self.current_step_index]

    @property
    def step_title(self) -> str:
        return self.current_step.replace("_", " ").title()
