from pathlib import Path
from archinstall.lib.args import ArchConfig
from archinstall.lib.models.device import (
    DiskLayoutConfiguration,
    DiskLayoutType,
    DeviceModification,
    PartitionModification,
    ModificationStatus,
    PartitionType,
    FilesystemType,
    Size,
    Unit
)
from archinstall.lib.models.users import User, Password
from archinstall.lib.models.locale import LocaleConfiguration
from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration
from archinstall.lib.models.authentication import AuthenticationConfiguration
from archinstall.lib.disk.device_handler import device_handler

def gui_config_to_arch_config(gui_config):
    """
    Shared utility to convert AcreetionOS frontend configuration (TUI or GUI) 
    into an archinstall.lib.args.ArchConfig object.

    Args:
        gui_config (dict): A dictionary containing user input from the TUI or GUI.
            Expected keys: disk, filesystem, hostname, username, password, sudo.

    Returns:
        ArchConfig: A populated configuration object ready for the installer backend.

    Raises:
        ValueError: If the specified disk device cannot be found.
    """
    arch_config = ArchConfig()
    arch_config.hostname = gui_config.get('hostname', 'acreetion-pc')
    arch_config.timezone = gui_config.get('timezone', 'UTC')
    
    arch_config.locale_config = LocaleConfiguration(
        kb_layout=gui_config.get('keyboardLayout', 'us'),
        sys_lang='en_US.UTF-8',
        sys_enc='UTF-8'
    )
    
    disk_path = Path(gui_config['disk'])
    device = device_handler.get_device(disk_path)
    if not device:
        raise ValueError(f"Device {disk_path} not found")
        
    fs_type = FilesystemType(gui_config.get('filesystem', 'btrfs'))
    
    # Standard default layout: 512MB boot, rest is /
    sector_size = device.device_info.sector_size
    total_size = device.device_info.total_size
    
    device_mod = DeviceModification(device, wipe=True)
    
    # Boot partition (512 MiB)
    boot_size = Size(512, Unit.MiB, sector_size)
    boot_partition = PartitionModification(
        status=ModificationStatus.Create,
        type=PartitionType.Primary,
        start=Size(1, Unit.MiB, sector_size),
        length=boot_size,
        mountpoint=Path('/boot'),
        fs_type=FilesystemType.Fat32
    )
    device_mod.add_partition(boot_partition)
    
    # Root partition
    root_start = boot_partition.start + boot_partition.length
    root_length = total_size.align() - root_start
    
    root_partition = PartitionModification(
        status=ModificationStatus.Create,
        type=PartitionType.Primary,
        start=root_start,
        length=root_length,
        mountpoint=Path('/'),
        fs_type=fs_type
    )
    device_mod.add_partition(root_partition)
    
    arch_config.disk_config = DiskLayoutConfiguration(
        config_type=DiskLayoutType.Default,
        device_modifications=[device_mod]
    )
    
    user_password = Password(plaintext=gui_config['password'])
    user = User(
        username=gui_config['username'],
        password=user_password,
        sudo=gui_config.get('sudo', True)
    )
    arch_config.auth_config = AuthenticationConfiguration(users=[user])
    
    arch_config.bootloader_config = BootloaderConfiguration(
        bootloader=Bootloader.Systemd,
        uki=False
    )
    
    return arch_config
