<?php

declare(strict_types=1);

namespace Lab;

final class Media
{
    /** @return list<array{id:string,label:string,path:string}> */
    public static function drives(): array
    {
        if (PHP_OS_FAMILY === 'Windows') {
            return self::windowsRemovable();
        }

        return self::unixVolumes();
    }

    public static function resolveDrive(string $id): ?array
    {
        foreach (self::drives() as $drive) {
            if ($drive['id'] === $id || $drive['path'] === $id) {
                return $drive;
            }
        }

        return null;
    }

    /** @return list<string> */
    public static function findImages(string $root, int $limit = 500): array
    {
        $root = realpath($root) ?: '';
        if ($root === '' || ! is_dir($root)) {
            return [];
        }
        $found = [];
        $iter = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($root, \FilesystemIterator::SKIP_DOTS)
        );
        foreach ($iter as $file) {
            if (! $file instanceof \SplFileInfo || ! $file->isFile()) {
                continue;
            }
            $name = $file->getFilename();
            if (str_starts_with($name, '.')) {
                continue;
            }
            $ext = strtolower($file->getExtension());
            if (! in_array($ext, ['jpg', 'jpeg', 'png', 'webp'], true)) {
                continue;
            }
            $path = $file->getPathname();
            if (! self::isUnder($root, $path)) {
                continue;
            }
            $found[] = $path;
            if (count($found) >= $limit) {
                break;
            }
        }
        sort($found, SORT_NATURAL | SORT_FLAG_CASE);

        return $found;
    }

    private static function isUnder(string $root, string $path): bool
    {
        $real = realpath($path);
        if ($real === false) {
            return false;
        }
        $root = rtrim(str_replace('\\', '/', $root), '/');
        $real = str_replace('\\', '/', $real);

        return $real === $root || str_starts_with($real, $root . '/');
    }

    /** @return list<array{id:string,label:string,path:string}> */
    private static function windowsRemovable(): array
    {
        $json = [];
        $cmd = 'powershell -NoProfile -Command "Get-CimInstance Win32_LogicalDisk -Filter ""DriveType=2"" | Select-Object DeviceID,VolumeName | ConvertTo-Json -Compress"';
        exec($cmd, $json);
        $raw = trim(implode('', $json));
        $rows = json_decode($raw, true);
        if (isset($rows['DeviceID'])) {
            $rows = [$rows];
        }
        $out = [];
        if (is_array($rows)) {
            foreach ($rows as $row) {
                $letter = (string) ($row['DeviceID'] ?? '');
                if ($letter === '') {
                    continue;
                }
                $path = $letter . '\\';
                $label = trim((string) ($row['VolumeName'] ?? '')) ?: $letter;
                $out[] = ['id' => $letter, 'label' => $label . ' (' . $letter . ')', 'path' => $path];
            }
        }
        if ($out !== []) {
            return $out;
        }
        $lines = [];
        exec('wmic logicaldisk where drivetype=2 get deviceid,volumename', $lines);
        foreach ($lines as $line) {
            $line = trim($line);
            if ($line === '' || str_starts_with(strtolower($line), 'deviceid')) {
                continue;
            }
            if (preg_match('/^([A-Z]:)\s*(.*)$/i', $line, $m)) {
                $letter = strtoupper($m[1]);
                $label = trim($m[2]) ?: $letter;
                $out[] = ['id' => $letter, 'label' => $label . ' (' . $letter . ')', 'path' => $letter . '\\'];
            }
        }

        return $out;
    }

    /** @return list<array{id:string,label:string,path:string}> */
    private static function unixVolumes(): array
    {
        $out = [];
        $skip = ['macintosh hd', 'macintosh hd - data', '/', 'home'];
        foreach (['/Volumes', '/media/' . (getenv('USER') ?: ''), '/run/media/' . (getenv('USER') ?: '')] as $base) {
            if (! is_dir($base)) {
                continue;
            }
            foreach (scandir($base) ?: [] as $name) {
                if ($name === '.' || $name === '..') {
                    continue;
                }
                if (in_array(strtolower($name), $skip, true)) {
                    continue;
                }
                $path = $base . '/' . $name;
                if (! is_dir($path) || ! is_readable($path)) {
                    continue;
                }
                $out[] = ['id' => $path, 'label' => $name, 'path' => $path];
            }
        }

        return $out;
    }
}
