<?php

namespace Modules\ProductCompat\Console;

use App\Product;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Modules\ProductCompat\Entities\Services\EnrichmentManager;

/**
 * Enrich products that are missing structured data, using the configured
 * providers (official site -> trusted site -> paid API).
 *
 *   php artisan productcompat:enrich --missing --limit=50
 *   php artisan productcompat:enrich --sku=SKU0245
 *
 * Safe by default: with no provider configured it processes nothing and just
 * reports that. All fetched data lands as needs_review for human approval.
 */
class EnrichProducts extends Command
{
    protected $signature = 'productcompat:enrich
        {--business= : Limit to a business_id}
        {--sku= : Limit to products whose SKU matches (LIKE)}
        {--missing : Only products that currently have no part number (for name-search sources)}
        {--with-brand : Restrict to products that have a brand (skips generic/non-part items)}
        {--has-partnumber : Only products that already have a part number (best for Icecat/code lookup)}
        {--skip-enriched : Skip products already enriched (resumable batches)}
        {--limit=50 : Max products to process}
        {--sleep=300 : Milliseconds to pause between products (politeness)}';

    protected $description = 'Enrich products missing part numbers from official/trusted/API sources.';

    public function handle(EnrichmentManager $manager): int
    {
        $available = array_map(fn ($p) => $p->key(), $manager->availableProviders());
        if (empty($available)) {
            $this->warn('No enrichment provider is configured/available. Set up a paid API key or brand/trusted URL templates in config/productcompat.php. Nothing to do.');
            return self::SUCCESS;
        }
        $this->info('Active providers (in order): ' . implode(' > ', $available));

        $query = Product::query()->select('products.*');
        if ($this->option('business')) {
            $query->where('business_id', (int) $this->option('business'));
        }
        if ($this->option('sku')) {
            $query->where('sku', 'like', '%' . $this->option('sku') . '%');
        }
        if ($this->option('missing')) {
            $query->whereNotExists(function ($q) {
                $q->select(DB::raw(1))->from('pc_part_numbers')
                    ->whereColumn('pc_part_numbers.product_id', 'products.id');
            });
        }
        if ($this->option('with-brand')) {
            $query->whereNotNull('brand_id');
        }
        if ($this->option('has-partnumber')) {
            $query->whereExists(function ($q) {
                $q->select(DB::raw(1))->from('pc_part_numbers')
                    ->whereColumn('pc_part_numbers.product_id', 'products.id');
            });
        }
        if ($this->option('skip-enriched')) {
            // Skip products that already have a successful enrichment attempt.
            $query->whereNotExists(function ($q) {
                $q->select(DB::raw(1))->from('pc_enrichment_log')
                    ->whereColumn('pc_enrichment_log.product_id', 'products.id')
                    ->where('pc_enrichment_log.status', 'success');
            });
        }
        $query->limit((int) $this->option('limit'));

        $products = $query->get();
        $this->info("Processing {$products->count()} product(s).");

        $totals = ['parts' => 0, 'devices' => 0, 'barcodes' => 0, 'hits' => 0];
        $sleep = (int) $this->option('sleep') * 1000; // ms -> us

        foreach ($products as $product) {
            $r = $manager->enrichProduct($product);
            $totals['parts'] += $r['parts'];
            $totals['devices'] += $r['devices'];
            $totals['barcodes'] += $r['barcodes'] ?? 0;
            if ($r['status'] === 'success') {
                $totals['hits']++;
                $this->line("  <fg=green>{$product->sku}</> +{$r['parts']} parts / +{$r['devices']} devices / +" . ($r['barcodes'] ?? 0) . " barcodes via {$r['provider']}");
            } else {
                $this->line("  {$product->sku} — {$r['status']}");
            }
            if ($sleep > 0) {
                usleep($sleep);
            }
        }

        $this->newLine();
        $this->table(['Products enriched', 'Part numbers added', 'Device models added', 'Barcodes added'],
            [[$totals['hits'], $totals['parts'], $totals['devices'], $totals['barcodes']]]);
        $this->info('Done. Added data is flagged needs_review — approve it in the Review Queue.');

        return self::SUCCESS;
    }
}
