<?php

declare(strict_types=1);

namespace Database\Seeders\Support;

use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;

final class SeederImageDownloader
{
    /**
     * Ensure a public file exists; download from URL or copy a local fallback.
     */
    public static function ensure(string $relativePath, string $sourceUrl, ?string $fallbackPath = null): string
    {
        $relativePath = ltrim(str_replace('\\', '/', $relativePath), '/');
        $absolutePath = public_path($relativePath);

        if (File::exists($absolutePath) && File::size($absolutePath) > 10_000) {
            return $relativePath;
        }

        File::ensureDirectoryExists(dirname($absolutePath));

        try {
            $response = Http::timeout(45)
                ->withHeaders(['User-Agent' => 'RievoDemoSeeder/1.0'])
                ->get($sourceUrl);

            if ($response->successful() && strlen($response->body()) > 10_000) {
                File::put($absolutePath, $response->body());

                return $relativePath;
            }
        } catch (\Throwable) {
            // Use bundled fallback below.
        }

        return self::copyFallback($relativePath, $fallbackPath);
    }

    /**
     * @param  list<string>  $relativePaths
     * @return list<string>
     */
    public static function ensureMany(array $relativePaths, string $sourceUrl): array
    {
        $paths = [];

        foreach ($relativePaths as $index => $relativePath) {
            $url = $index === 0 ? $sourceUrl : $sourceUrl . '&sig=' . $index;
            $paths[] = self::ensure($relativePath, $url);
        }

        return $paths;
    }

    private static function copyFallback(string $relativePath, ?string $fallbackPath = null): string
    {
        $candidates = array_values(array_filter([
            $fallbackPath,
            'files/gav.jpg',
            'files/goosfand.jpg',
            'files/gav-1.jpg',
            'files/goosfand-1.jpg',
            'files/default-post.png',
        ]));

        foreach ($candidates as $fallback) {
            $source = public_path($fallback);

            if (File::exists($source)) {
                File::ensureDirectoryExists(dirname(public_path($relativePath)));
                File::copy($source, public_path($relativePath));

                return $relativePath;
            }
        }

        return $relativePath;
    }
}
