<?php

namespace Database\Factories\Concerns;

use Illuminate\Support\Facades\File;

trait CopiesSeederImages
{
    /**
     * Cached pools of copied images keyed by destination folder.
     * Images are copied once from the source and then reused,
     * avoiding redundant file I/O that causes timeouts on shared hosting.
     *
     * @var array<string, list<string>>
     */
    protected static array $imagePool = [];

    /**
     * Copy a random image from the seeder images directory to the storage directory.
     *
     * Uses a pre-built pool per destination folder so each source image is
     * only copied once, regardless of how many models reference it.
     */
    protected function copyRandomSeederImage(string $sourceFolder, string $destinationFolder): string
    {
        if (! isset(static::$imagePool[$destinationFolder])) {
            static::$imagePool[$destinationFolder] = $this->buildImagePool($sourceFolder, $destinationFolder);
        }

        $pool = static::$imagePool[$destinationFolder];

        if (empty($pool)) {
            throw new \RuntimeException("No images found in seeder_images/{$sourceFolder}");
        }

        return $pool[array_rand($pool)];
    }

    /**
     * Copy all source images once into the destination and return their paths.
     *
     * @return list<string>
     */
    private function buildImagePool(string $sourceFolder, string $destinationFolder): array
    {
        $sourceDir = resource_path("seeder_images/{$sourceFolder}");
        $destinationDir = storage_path("app/public/{$destinationFolder}");

        if (! File::exists($destinationDir)) {
            File::makeDirectory($destinationDir, 0755, true);
        }

        if (! File::exists($sourceDir)) {
            return [];
        }

        $images = File::files($sourceDir);

        if (empty($images)) {
            return [];
        }

        $pool = [];

        foreach ($images as $image) {
            $extension = $image->getExtension();
            $newFileName = uniqid().'.'.$extension;
            $destinationPath = $destinationDir.'/'.$newFileName;

            File::copy($image->getPathname(), $destinationPath);
            $pool[] = "{$destinationFolder}/{$newFileName}";
        }

        return $pool;
    }
}
