<?php

declare(strict_types=1);

namespace Lab;

final class Windows
{
    public static function browseFolder(string $current = '', string $title = 'Επιλογή φακέλου'): string
    {
        if (PHP_OS_FAMILY === 'Darwin') {
            return self::browseFolderMac($current, $title);
        }
        if (PHP_OS_FAMILY !== 'Windows') {
            return '';
        }
        set_time_limit(0);
        $picker = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'pick-folder.ps1';
        if (is_file($picker)) {
            $cmd = 'powershell -NoProfile -STA -ExecutionPolicy Bypass -File ' . escapeshellarg($picker)
                . ' -Title ' . escapeshellarg($title)
                . ' -Start ' . escapeshellarg($current);
            $lines = [];
            exec($cmd, $lines);

            return trim(implode("\n", $lines));
        }

        $titleJson = json_encode($title, JSON_UNESCAPED_UNICODE);
        $pathJson = json_encode($current, JSON_UNESCAPED_UNICODE);
        $script = <<<PS
Add-Type -AssemblyName System.Windows.Forms
\$d = New-Object System.Windows.Forms.FolderBrowserDialog
\$d.Description = $titleJson
\$d.ShowNewFolderButton = \$true
if ($pathJson -ne '' -and (Test-Path -LiteralPath $pathJson)) { \$d.SelectedPath = $pathJson }
\$r = \$d.ShowDialog()
if (\$r -eq [Windows.Forms.DialogResult]::OK) {
    [Console]::OutputEncoding = [Text.UTF8Encoding]::new()
    [Console]::Out.Write(\$d.SelectedPath)
}
PS;

        return trim(self::run($script, true));
    }

    public static function openAddPrinter(): bool
    {
        if (PHP_OS_FAMILY === 'Darwin') {
            exec('open ' . escapeshellarg('x-apple.systempreferences:com.apple.Print-Scan-Settings.extension'));
            return true;
        }
        if (PHP_OS_FAMILY !== 'Windows') {
            return false;
        }
        pclose(popen('cmd /c start "" rundll32 printui.dll,PrintUIEntry /il', 'r'));

        return true;
    }

    /** @return array{ok:bool,error:string} */
    public static function connectPrinter(string $name): array
    {
        $name = trim($name);
        if ($name === '') {
            return ['ok' => false, 'error' => 'Γράψε όνομα ή διαδρομή εκτυπωτή.'];
        }
        if (PHP_OS_FAMILY === 'Darwin') {
            return ['ok' => false, 'error' => 'Στον Mac πρόσθεσε τον εκτυπωτή από Ρυθμίσεις → Εκτυπωτές και σαρωτές.'];
        }
        if (PHP_OS_FAMILY !== 'Windows') {
            return ['ok' => false, 'error' => 'Η σύνδεση εκτυπωτή γίνεται στα Windows.'];
        }
        $n = json_encode($name, JSON_UNESCAPED_UNICODE);
        $script = <<<PS
\$ErrorActionPreference = 'Stop'
try {
    Add-Printer -ConnectionName $n
    'OK'
} catch {
    \$msg = \$_.Exception.Message
    if (\$msg -match 'already|υπάρχει|exists') {
        'OK'
    } else {
        try {
            Start-Process -FilePath rundll32 -ArgumentList @('printui.dll,PrintUIEntry','/in','/n',$n)
            'OK'
        } catch {
            \$msg
        }
    }
}
PS;
        $out = trim(self::run($script, false));
        if ($out === 'OK' || $out === '') {
            return ['ok' => true, 'error' => ''];
        }

        return ['ok' => false, 'error' => $out];
    }

    private static function browseFolderMac(string $current, string $title): string
    {
        $title = str_replace(['\\', '"'], ['\\\\', '\\"'], $title);
        $script = 'try' . "\n" . 'POSIX path of (choose folder with prompt "' . $title . '"';
        $current = trim($current);
        if ($current !== '' && is_dir($current)) {
            $path = str_replace(['\\', '"'], ['\\\\', '\\"'], $current);
            $script .= ' default location (POSIX file "' . $path . '")';
        }
        $script .= ')' . "\n" . 'on error' . "\n" . '""' . "\n" . 'end try';
        $file = sys_get_temp_dir() . '/labmac-' . bin2hex(random_bytes(6)) . '.scpt';
        file_put_contents($file, $script);
        $lines = [];
        exec('osascript ' . escapeshellarg($file), $lines);
        @unlink($file);

        return trim(implode("\n", $lines));
    }

    private static function run(string $script, bool $sta): string
    {
        $dir = sys_get_temp_dir();
        $file = $dir . DIRECTORY_SEPARATOR . 'labwin-' . bin2hex(random_bytes(6)) . '.ps1';
        file_put_contents($file, $script);
        $cmd = 'powershell -NoProfile -ExecutionPolicy Bypass'
            . ($sta ? ' -STA' : ' -NonInteractive')
            . ' -File ' . escapeshellarg($file);
        $lines = [];
        exec($cmd, $lines);
        @unlink($file);

        return implode("\n", $lines);
    }
}
