<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Services\Ads\MajidApiClient;
use App\Jobs\BamaSearchJob;
use App\Jobs\DivarScrapeJob;
use Illuminate\Support\Facades\DB;

class ScrapeSpecificCars extends Command
{
    protected $signature = 'ads:scrape-cars {brand} {--model=} {--force} {--city-id= : City ID to filter by} {--sources= : Comma-separated sources (bama,divar)} {--session-id= : Search session ID} {--user-id= : User ID for tracking}';
    protected $description = 'Scrape specific car brand/model from Bama and Divar with user-specific tracking';

    private array $carMappings = [
        '206' => ['brand' => 'peugeot', 'model' => '206'],
        'ساینا' => ['brand' => 'saina', 'model' => 'saina'],
        'کوییک' => ['brand' => 'quick', 'model' => 'quick'],
        'تیبا' => ['brand' => 'tiba', 'model' => 'tiba'],
        'تیبا 2' => ['brand' => 'tiba', 'model' => 'tiba2'],
        '207' => ['brand' => 'peugeot', 'model' => '207'],
        'پراید' => ['brand' => 'pride', 'model' => 'pride'],
    ];

    public function handle()
    {
        $brand = $this->argument('brand');
        $model = $this->option('model');
        $force = $this->option('force');
        $cityId = $this->option('city-id');
        $sources = $this->option('sources') ? explode(',', $this->option('sources')) : ['bama'];
        $sessionId = $this->option('session-id');
        $tgUserId = $this->option('user-id');
        $internalUserId = $tgUserId ? DB::table('users')->where('tg_id', (string) $tgUserId)->value('id') : null;

        $this->info("🚗 Scraping cars: {$brand}" . ($model ? " - {$model}" : ""));

        // Check if already scraped recently
        if (!$force) {
            $lastScrape = DB::table('ads_raw')
                ->where('source', 'bama')
                ->where('created_at', '>', now()->subHours(2))
                ->where('payload_json', 'like', '%' . $brand . '%')
                ->exists();

            if ($lastScrape) {
                $this->warn('⚠️  This car was scraped recently. Use --force to scrape anyway.');
                return 0;
            }
        }

        // Get search terms
        $searchTerms = $this->getSearchTerms($brand, $model);

        $totalAds = 0;
        foreach ($searchTerms as $searchTerm) {
            $this->info("  🔍 Searching: {$searchTerm}");

            try {
                // Only scrape from Bama if it's in sources
                if (in_array('bama', $sources)) {
                    $this->info("    🔍 Scraping Bama for: {$searchTerm}");
                    $job = new BamaSearchJob($searchTerm, 1, false, $cityId, $internalUserId, $sessionId);
                    $job->handle();
                    $this->info("    ✅ Bama scraping completed");
                }

                // Count ads for this search
                $count = DB::table('ads_raw')
                    ->where('source', 'bama')
                    ->where('created_at', '>', now()->subMinutes(5))
                    ->where('payload_json', 'like', '%' . $searchTerm . '%')
                    ->count();

                $totalAds += $count;
                $this->info("    ✅ Found {$count} ads");

            } catch (\Exception $e) {
                $this->error("    ❌ Failed: " . $e->getMessage());
            }
        }

        // Also scrape from Divar if it's in sources
        if (in_array('divar', $sources)) {
            $this->info("🔍 Scraping from Divar...");

            // Resolve Divar city slug (English) for known cities
            $citySlug = 'tehran';
            if ($cityId) {
                $city = DB::table('cities')->where('id', $cityId)->first();
                if ($city) {
                    $name = trim($city->name);
                    $slugMap = [
                        'تهران' => 'tehran',
                        'اصفهان' => 'isfahan',
                        'مشهد' => 'mashhad',
                        'تبریز' => 'tabriz',
                        'شیراز' => 'shiraz',
                        'کرج' => 'karaj',
                    ];
                    $citySlug = $slugMap[$name] ?? 'tehran';
                }
            }

            // Build Divar URLs using hierarchical structure from spec
            $urls = $this->buildDivarUrls($citySlug, $brand, $model);

            foreach ($urls as $index => $url) {
                try {
                    if ($index > 0) {
                        sleep(3); // Increased delay for rate limiting
                    }

                    $this->info("    🔍 Scraping Divar: {$url}");
                    $divarJob = new \App\Jobs\DivarScrapeJob($url, false, $cityId, $brand, $model, $internalUserId, $sessionId);
                    $divarJob->handle();
                    $this->info("    ✅ Divar URL processed: {$url}");
                } catch (\Exception $e) {
                    $this->warn("    ⚠️ Divar failed (rate limited?): " . $e->getMessage());
                }
            }
        }

        // Process and score the new ads
        $this->info("🎯 Processing and scoring ads...");
        try {
            $scoringJob = new \App\Jobs\ScoreOpportunitiesJob();
            $scoringJob->handle();
            $this->info("    ✅ Scoring completed");
        } catch (\Exception $e) {
            $this->warn("    ⚠️ Scoring failed: " . $e->getMessage());
        }

        // Note: Tagging is handled by ScoreOpportunitiesJob automatically
        // No need for additional tagging here as it would conflict

        // Get opportunities for this specific brand
        $opportunities = DB::table('opportunities')
            ->where('created_at', '>', now()->subMinutes(5))
            ->where(function($query) use ($brand) {
                $query->where('brand', 'like', '%' . $brand . '%')
                      ->orWhere('brand', 'like', '%' . $this->getBrandMapping($brand) . '%');
            })
            ->get();

        $this->info("📊 Results:");
        $this->info("  Raw Ads: {$totalAds}");
        $this->info("  Opportunities: {$opportunities->count()}");

        if ($opportunities->isEmpty()) {
            $this->warn("⚠️  No opportunities found for {$brand}");
            $this->info("💡 This might be due to:");
            $this->info("  - Low scores (below 0.6)");
            $this->info("  - Missing required fields (price, year, etc.)");
            $this->info("  - Normalization issues");
            return 0;
        }

        // Show top opportunities
        $topOpportunities = $opportunities->take(5);

        if ($topOpportunities->isNotEmpty()) {
            $this->newLine();
            $this->info("🏆 Top Opportunities:");
            $this->newLine();

            foreach ($topOpportunities as $index => $opp) {
                $this->line("  " . ($index + 1) . ". {$opp->brand} {$opp->model} ({$opp->year})");
                $this->line("     💰 قیمت: " . number_format($opp->price) . " میلیون تومان");
                $this->line("     ⭐ امتیاز: " . number_format($opp->score, 2));
                $this->line("     🔗 لینک: {$opp->link}");
                $this->newLine();
            }
        }

        $this->info("✅ Car scraping completed!");
        return 0;
    }

    private function getSearchTerms(string $brand, ?string $model): array
    {
        $searchTerms = [];

        // Add brand search
        $searchTerms[] = $brand;

        // Add model search if provided
        if ($model) {
            $searchTerms[] = $model;
            $searchTerms[] = "{$brand} {$model}";
        }

        // Add common variations
        if (isset($this->carMappings[$brand])) {
            $mapping = $this->carMappings[$brand];
            $searchTerms[] = $mapping['brand'];
            if ($model) {
                $searchTerms[] = "{$mapping['brand']} {$model}";
            }
        }

        // Add Persian variations
        $persianTerms = [
            '206' => 'پژو 206',
            'ساینا' => 'ساینا',
            'کوییک' => 'کوییک',
            'تیبا' => 'تیبا',
            'تیبا 2' => 'تیبا 2',
            '207' => 'پژو 207',
            'پراید' => 'پراید',
        ];

        if (isset($persianTerms[$brand])) {
            $searchTerms[] = $persianTerms[$brand];
        }

        return array_unique($searchTerms);
    }

    private function getBrandMapping(string $carBrand): string
    {
        $mappings = [
            '206' => 'peugeot',
            'ساینا' => 'saina',
            'کوییک' => 'quick',
            'تیبا' => 'tiba',
            'تیبا 2' => 'tiba',
            '207' => 'peugeot',
            'پراید' => 'pride',
        ];

        return $mappings[$carBrand] ?? $carBrand;
    }

    private function buildDivarUrls(string $citySlug, string $brand, ?string $model): array
    {
        $urls = [];

        // Get brand mapping
        $brandKey = $this->getBrandMapping($brand);

        // Use only query-based search for better results
        $urls[] = "https://divar.ir/s/{$citySlug}/car?q=" . urlencode($brand);

        // Add model-specific search if model is provided
        if ($model) {
            $urls[] = "https://divar.ir/s/{$citySlug}/car?q=" . urlencode($brand . ' ' . $model);
        }

        return array_unique($urls);
    }
}
