<?php

namespace App\Console\Commands;

use App\Models\Product;
use App\Models\ProductVersion;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;

class ImportMecaprogramsVersions extends Command
{
    protected $signature = 'mecaprograms:import-versions
        {--product= : Import versions for a specific product slug}
        {--limit= : Max products to process}
        {--delay=500 : Milliseconds between requests}
        {--dry-run : Print what would be imported without saving}';

    protected $description = 'Import product versions from mecaprograms.com product pages';

    protected string $baseUrl = 'https://mecaprograms.com';

    protected int $imported = 0;
    protected int $skipped = 0;
    protected int $failed = 0;

    public function handle(): int
    {
        ini_set('memory_limit', '512M');
        $this->info('Fetching mecaprograms.com sitemap to discover product URLs...');

        $productUrls = $this->fetchSitemapProducts();
        $this->info('Found ' . count($productUrls) . ' product URLs in sitemap');

        if (empty($productUrls)) {
            return Command::FAILURE;
        }

        $limit = (int) ($this->option('limit') ?: count($productUrls));
        $productUrls = array_slice($productUrls, 0, $limit);

        $filterSlug = $this->option('product');

        $this->newLine();
        $this->info('Processing product pages for versions...');

        foreach ($productUrls as $url) {
            $slug = basename(parse_url($url, PHP_URL_PATH));

            if ($filterSlug && $slug !== $filterSlug) {
                continue;
            }

            $product = Product::where('slug', $slug)->first();
            if (!$product) {
                $this->line("  Skipped (not in local DB): {$slug}");
                $this->skipped++;
                continue;
            }

            $this->scrapeVersions($product);

            if (gc_enabled()) {
                gc_collect_cycles();
            }
            usleep((int) $this->option('delay') * 1000);
        }

        $this->newLine();
        $this->table(
            ['Imported', 'Skipped', 'Failed'],
            [[$this->imported, $this->skipped, $this->failed]]
        );

        return Command::SUCCESS;
    }

    protected function fetchSitemapProducts(): array
    {
        $response = Http::withOptions(['verify' => false])
            ->withHeaders(['User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'])
            ->timeout(30)
            ->get("{$this->baseUrl}/sitemap.xml");

        if (!$response->successful()) {
            $this->error("Failed to fetch sitemap (HTTP {$response->status()})");
            return [];
        }

        preg_match_all(
            '!https://mecaprograms\.com/software/[^<]+!',
            html_entity_decode($response->body()),
            $matches
        );

        return $matches[0] ?? [];
    }

    protected function scrapeVersions(Product $product): void
    {
        $slug = $product->slug;
        $url = "{$this->baseUrl}/software/{$slug}";
        $this->line("  Fetching: {$url}");

        try {
            $response = Http::withOptions(['verify' => false])
                ->withHeaders([
                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
                    'Accept' => 'text/html',
                ])->timeout(30)->get($url);

            if (!$response->successful()) {
                $this->warn("  Failed (HTTP {$response->status()})");
                $this->failed++;
                return;
            }

            $html = $response->body();
            $versions = $this->parseVersions($html);

            if (empty($versions)) {
                $this->line("  No versions found for: {$slug}");
                $this->skipped++;
                return;
            }

            foreach ($versions as $index => $versionLabel) {
                $this->importVersion($product, $versionLabel, $index);
            }

        } catch (\Exception $e) {
            $this->error("  Error: {$e->getMessage()}");
            $this->failed++;
        }
    }

    protected function parseVersions(string $html): array
    {
        $versions = [];

        preg_match_all(
            '/>\s*(\d+[\d.]*\s*(?:SP\d+|R\d+|UPDATE|REV|V\d+)?\s*\[?\d{4}(?:\.\d{2})?\]?)\s*</',
            $html,
            $matches
        );

        $seen = [];
        foreach ($matches[1] as $v) {
            $v = trim(html_entity_decode($v));
            $v = preg_replace('/\s+/', ' ', $v);
            if (!empty($v) && !isset($seen[$v])) {
                $seen[$v] = true;
                $versions[] = $v;
            }
        }

        return $versions;
    }

    protected function importVersion(Product $product, string $versionLabel, int $index): void
    {
        $existing = ProductVersion::where('product_id', $product->id)
            ->where('version', $versionLabel)
            ->first();

        if ($existing) {
            $this->line("  Skipped (exists): {$versionLabel}");
            $this->skipped++;
            return;
        }

        if ($this->option('dry-run')) {
            $this->line("  Would import version: {$versionLabel} for {$product->name}");
            $this->imported++;
            return;
        }

        try {
            ProductVersion::create([
                'product_id' => $product->id,
                'version' => $versionLabel,
                'price' => $product->price,
                'sale_price' => $product->sale_price,
                'order' => $index,
                'is_active' => true,
            ]);

            $this->line("  Imported version: {$versionLabel}");
            $this->imported++;

        } catch (\Exception $e) {
            $this->error("  Failed to import version {$versionLabel}: {$e->getMessage()}");
            $this->failed++;
        }
    }
}
