<?php

namespace App\Console\Commands;

use App\Models\Page;
use App\Models\Post;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\Finder\Finder;

class ImportLocalMedia extends Command
{
    protected $signature = 'ansh:import-media {source : Path to the local WordPress export folder}';

    protected $description = 'Replace ansh.com hotlinked images/PDFs in page and post content with files copied from a local WordPress export';

    /** @var array<string, string> basename (lowercased) => absolute path on disk */
    private array $index = [];

    private int $copied = 0;

    private int $replaced = 0;

    /** @var array<int, string> */
    private array $missing = [];

    public function handle(): int
    {
        $source = rtrim($this->argument('source'), '/\\');

        if (! is_dir($source)) {
            $this->error("Source folder not found: {$source}");

            return self::FAILURE;
        }

        $this->info('Indexing files in the export folder…');
        $this->buildIndex($source);
        $this->info(count($this->index) . ' files indexed.');

        foreach (Page::all() as $page) {
            $original = $page->content;
            $page->content = $this->rewriteContent($page->content);
            if ($page->content !== $original) {
                $page->save();
            }
        }

        foreach (Post::all() as $post) {
            $original = $post->content;
            $post->content = $this->rewriteContent($post->content);
            if ($post->content !== $original) {
                $post->save();
            }
        }

        $this->info("Copied {$this->copied} new files, replaced {$this->replaced} URL occurrences.");

        if ($this->missing) {
            $unique = array_values(array_unique($this->missing));
            $this->warn(count($unique) . ' referenced file(s) not found locally (left as-is):');
            foreach ($unique as $url) {
                $this->line(' - ' . $url);
            }
        }

        return self::SUCCESS;
    }

    private function buildIndex(string $source): void
    {
        $finder = new Finder();
        $finder->files()->in($source)->exclude(['wp-admin', 'wp-includes', 'cgi-bin']);

        foreach ($finder as $file) {
            $key = strtolower($file->getFilename());
            // Prefer the first match (shallower/root files over deeply nested duplicates).
            if (! isset($this->index[$key])) {
                $this->index[$key] = $file->getPathname();
            }
        }
    }

    private function rewriteContent(?string $content): ?string
    {
        if (! $content) {
            return $content;
        }

        return preg_replace_callback(
            '#https://ansh\.com/[^"\'\s)]+\.(jpg|jpeg|png|gif|webp|svg|pdf)#i',
            function ($m) {
                $url = $m[0];
                $basename = strtolower(basename(parse_url($url, PHP_URL_PATH)));

                if (! isset($this->index[$basename])) {
                    $this->missing[] = $url;

                    return $url;
                }

                $localFile = $this->index[$basename];
                $storagePath = 'imported/' . basename($localFile);

                if (! Storage::disk('public')->exists($storagePath)) {
                    Storage::disk('public')->put($storagePath, file_get_contents($localFile));
                    $this->copied++;
                }

                $this->replaced++;

                return Storage::disk('public')->url($storagePath);
            },
            $content
        );
    }
}
