<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Services\VipResellerPpobService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class SyncVipResellerPpob extends Command
{
    protected $signature = 'vipreseller:sync-ppob {--force : Force sync even if recently synced}';
    protected $description = 'ULTRA SMART Sync - 100% Preserve Manual Edits (Image, Description, Name, Price)';

    private $ppobService;
    private $stats = ['created' => 0, 'updated' => 0, 'skipped' => 0, 'preserved' => 0];

    public function __construct(VipResellerPpobService $ppobService)
    {
        parent::__construct();
        $this->ppobService = $ppobService;
    }

    public function handle()
    {
        $this->info('🚀 ULTRA SMART SYNC - Starting...');
        $this->info('   🛡️  Manual edits will be 100% preserved!');
        $this->newLine();

        $priceList = $this->ppobService->fetchPpobProducts();
        if (empty($priceList)) {
            $this->error('❌ API Empty or HTML Response. Check logs.');
            return 1;
        }

        $this->info('✅ Fetched ' . count($priceList) . ' items from API.');

        // --- STEP 1: SYNC CATEGORIES (ULTRA SMART - Never Override Manual Changes) ---
        $this->info('📂 Syncing PPOB categories (Preserving Images & Manual Edits)...');
        
        foreach ($priceList as $item) {
            $brandName = $item['brand'] ?? null;
            $apiCategory = $item['category'] ?? '';
            
            // Skip if: no brand, hardcore game, or blacklisted
            if (!$brandName || $this->isHardcoreGame($brandName) || $this->isBlacklisted($brandName)) {
                continue;
            }

            $brandCode = $this->normalizeBrandName($brandName);
            
            // Check product availability
            $hasAvailable = collect($priceList)
                ->where('brand', $brandName)
                ->where('status', 'available')
                ->count();
                
            if ($hasAvailable === 0) continue;

            $type = $this->detectPpobType($brandName, $apiCategory);
            $slug = Str::slug($brandName . '-' . $type);
            $label = $this->getDynamicLabel($type);
            $inputType = $this->getInputType($type);
            
            // Auto description
            $description = match($type) {
                'pulsa'       => "Isi ulang pulsa atau paket data $brandName harga termurah dan proses otomatis.",
                'ewallet'     => "Top up saldo $brandName instan 24 jam. Saldo langsung masuk dalam hitungan detik.",
                'pln'         => "Beli token listrik PLN atau bayar tagihan listrik $brandName dengan harga agen.",
                'streaming'   => "Langganan premium $brandName resmi dan aman hanya di Ryll Store.",
                'subscription'=> "Akses langganan $brandName murah dan legal untuk hiburan kamu.",
                'voucher'     => "Voucher digital $brandName. Pilih nominal, checkout, langsung dikirim kode voucher.",
                default       => "Layanan $brandName harga terbaik, proses cepat dan aman."
            };

            $existingCategory = DB::table('categories')->where('slug', $slug)->first();

            if (!$existingCategory) {
                // ====================================
                // CREATE NEW CATEGORY
                // ====================================
                DB::table('categories')->insert([
                    'name'          => $brandName,
                    'slug'          => $slug,
                    'brand_code'    => $brandCode,
                    'category_type' => $type,
                    'input_type'    => $inputType,
                    'description'   => $description,
                    'api_filter'    => json_encode([
                        'target_type' => 'default',
                        'id_label'    => $label,
                        'check_code'  => ($type === 'pln') ? 'pln' : null
                    ]),
                    'is_active'     => true,
                    'manual_image'  => false,  // Track: no manual image yet
                    'manual_description' => false,
                    'manual_name'   => false,
                    'created_at'    => now(),
                    'updated_at'    => now(),
                ]);
                
                $this->info("  ✨ Created: $brandName [$type]");
                $this->stats['created']++;
            } else {
                // ====================================
                // UPDATE EXISTING - PRESERVE MANUAL EDITS
                // Only update: category_type, input_type if not manually changed
                // NEVER touch: image, name, description if manual flags are true
                // ====================================
                $updateData = [];
                
                // Update category_type & input_type (business logic, safe to update)
                if ($existingCategory->category_type !== $type) {
                    $updateData['category_type'] = $type;
                    $updateData['input_type'] = $inputType;
                }
                
                // Update description ONLY if NOT manually edited
                if (!$existingCategory->manual_description && empty($existingCategory->image)) {
                    $updateData['description'] = $description;
                }
                
                // Update api_filter (safe, technical field)
                $updateData['api_filter'] = json_encode([
                    'target_type' => 'default',
                    'id_label'    => $label,
                    'check_code'  => ($type === 'pln') ? 'pln' : null
                ]);
                
                if (!empty($updateData)) {
                    $updateData['updated_at'] = now();
                    DB::table('categories')
                        ->where('id', $existingCategory->id)
                        ->update($updateData);
                    
                    $this->stats['updated']++;
                }
                
                // Track preserved items
                if ($existingCategory->manual_image || $existingCategory->manual_description || $existingCategory->manual_name) {
                    $this->stats['preserved']++;
                }
            }
        }

        // --- STEP 2: SYNC PRODUCTS (ULTRA SMART) ---
        $this->info('📦 Syncing PPOB products (Preserving ALL Manual Edits)...');
        
        $categories = DB::table('categories')
            ->where('is_active', true)
            ->whereIn('category_type', ['pulsa', 'ewallet', 'pln', 'streaming', 'voucher', 'subscription'])
            ->get();

        $this->info('   Found ' . $categories->count() . ' active PPOB categories');
        $bar = $this->output->createProgressBar($categories->count());
        $bar->start();

        foreach ($categories as $category) {
            $productCount = $this->syncCategoryProducts($category, $priceList);
            $bar->advance();
        }

        $bar->finish();
        $this->newLine(2);

        // --- STEP 3: AUTO-DELETE CATEGORIES WITH 0 PRODUCTS ---
        $this->info('🧹 Cleaning up categories with 0 products...');
        
        $emptyCategories = DB::table('categories')
            ->whereIn('category_type', ['pulsa', 'ewallet', 'pln', 'streaming', 'voucher', 'subscription'])
            ->whereNotExists(function ($query) {
                $query->select(DB::raw(1))
                      ->from('products')
                      ->whereRaw('products.category_id = categories.id');
            })
            ->where('manual_image', false)  // Only delete if no manual image
            ->where('manual_description', false)  // Only delete if no manual description
            ->get();

        foreach ($emptyCategories as $cat) {
            DB::table('categories')->where('id', $cat->id)->delete();
            $this->warn("  🗑️ Deleted empty category: {$cat->name}");
        }

        $this->newLine();
        $this->info("✅ ULTRA SMART SYNC Complete!");
        $this->info("   Created: {$this->stats['created']} categories");
        $this->info("   Updated: {$this->stats['updated']} items");
        $this->info("   🛡️  Preserved: {$this->stats['preserved']} manual edits");
        $this->info("   Skipped: {$this->stats['skipped']} products");
        
        return 0;
    }

    /**
     * ULTRA SMART Product Sync - Preserve ALL manual changes
     */
    private function syncCategoryProducts($category, $priceList)
    {
        $syncCount = 0;
        
        $filtered = array_filter($priceList, function($item) use ($category) {
            return $this->normalizeBrandName($item['brand'] ?? '') === $category->brand_code;
        });

        foreach ($filtered as $product) {
            $sku = $product['code'] ?? null;
            
            if (!$sku) {
                $this->stats['skipped']++;
                continue;
            }
            
            if (($product['status'] ?? '') !== 'available') {
                $this->stats['skipped']++;
                continue;
            }

            $basePrice = is_array($product['price']) 
                ? ($product['price']['basic'] ?? 0) 
                : $product['price'];
                
            if ($basePrice <= 0) {
                $this->stats['skipped']++;
                continue;
            }

            // Calculate selling price with 5% markup for PPOB
            $sellingPrice = round($basePrice * 1.05);
            $apiNote = $product['note'] ?? 'Proses otomatis 24 jam.';
            $apiName = $product['service'] ?? ($product['brand'] . ' ' . $sku);

            $existing = DB::table('products')->where('sku', $sku)->first();
            
            if ($existing) {
                // ====================================
                // UPDATE MODE - ULTRA SMART!
                // PRESERVE: image, name, description, price IF manually edited
                // UPDATE: base_price, stock (always safe to update)
                // ====================================
                $updateData = [
                    'base_price' => $basePrice,
                    'stock' => 9999,
                    'unlimited_stock' => 1,
                    'seller_product_status' => 1,
                    'updated_at' => now(),
                ];
                
                // Update name ONLY if NOT manually edited
                if (!$existing->manual_name) {
                    $updateData['name'] = $apiName;
                }
                
                // Update selling_price ONLY if NOT manually edited
                if (!$existing->manual_price) {
                    $updateData['selling_price'] = $sellingPrice;
                }
                
                // Update description ONLY if NOT manually edited
                if (!$existing->manual_description) {
                    $updateData['description'] = $apiNote;
                }
                
                // NEVER update image, category_id - always preserved
                
                DB::table('products')
                    ->where('id', $existing->id)
                    ->update($updateData);
                
                // Track preserved items
                if ($existing->manual_image || $existing->manual_description || 
                    $existing->manual_name || $existing->manual_price) {
                    $this->stats['preserved']++;
                }
                
                $this->stats['updated']++;
            } else {
                // ====================================
                // INSERT MODE - New Product
                // ====================================
                DB::table('products')->insert([
                    'category_id' => $category->id,
                    'name' => $apiName,
                    'sku' => $sku,
                    'api_code' => $sku,
                    'base_price' => $basePrice,
                    'selling_price' => $sellingPrice,
                    'description' => $apiNote,
                    'stock' => 9999,
                    'unlimited_stock' => 1,
                    'seller_product_status' => 1,
                    'manual_image' => false,
                    'manual_description' => false,
                    'manual_name' => false,
                    'manual_price' => false,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);
                
                $this->stats['created']++;
            }
            
            $syncCount++;
        }
        
        return $syncCount;
    }

    /**
     * Detect PPOB category type with GEMINI fixed
     */
    private function detectPpobType($brand, $category)
    {
        $brand = strtoupper($brand);
        $category = strtoupper($category);

        // PRIORITY 1: Subscription Apps (GEMINI INCLUDED!)
        $subKeywords = [
            'ALIGHT', 'CANVA', 'YOUTUBE', 'SPOTIFY', 'DISNEY', 'PRIME', 
            'VIDIO', 'CHATGPT', 'GRAMMARLY', 'NOTION', 'GEMINI',
            'CAPCUT', 'PICSART', 'KINEMASTER', 'DISCORD', 'PERPLEXITY'
        ];
        foreach ($subKeywords as $sk) {
            if (str_contains($brand, $sk)) return 'subscription';
        }

        // PRIORITY 2: Streaming
        $streamingKeywords = [
            'NETFLIX', 'VIU', 'IQIYI', 'WETV', 'VISION', 'MOLA',
            'HBO', 'APPLE TV', 'BSTATION'
        ];
        foreach ($streamingKeywords as $stream) {
            if (str_contains($brand, $stream)) return 'streaming';
        }

        // PRIORITY 3: Pulsa/Data
        $selular = [
            'TRI', 'XL', 'AXIS', 'INDOSAT', 'TELKOMSEL', 'SMARTFREN', 
            'BY.U', 'CELCOM', 'DIGI', 'CHINA TOPUP'
        ];
        foreach ($selular as $s) {
            if (str_contains($brand, $s)) return 'pulsa';
        }
        
        if (str_contains($category, 'PULSA') || str_contains($category, 'DATA')) {
            return 'pulsa';
        }
        
        // PRIORITY 4: PLN/Utilities
        if (str_contains($brand, 'PLN') || str_contains($brand, 'TOKEN') || str_contains($brand, 'WIFI ID')) {
            return 'pln';
        }
        
        // PRIORITY 5: E-Wallet
        if (Str::contains($brand, ['DANA', 'OVO', 'GOPAY', 'LINKAJA', 'SHOPEEPAY', 'BRIZZI'])) {
            return 'ewallet';
        }
        
        // PRIORITY 6: Voucher
        return 'voucher';
    }

    private function getInputType($categoryType)
    {
        return match($categoryType) {
            'pulsa', 'ewallet' => 'phone',
            'pln' => 'username',
            'streaming', 'subscription' => 'email',
            'voucher' => 'voucher',
            default => 'phone'
        };
    }

    private function isHardcoreGame($brand)
    {
        $brand = strtoupper($brand);
        $games = [
            'MOBILE LEGENDS', 'FREE FIRE', 'PUBG', 'VALORANT', 'GENSHIN', 
            'HONKAI', 'ARENA OF VALOR', 'ACE RACER', 'SAUSAGE MAN', 
            'ONE PUNCH MAN', 'CALL OF DUTY', 'LEAGUE OF LEGENDS',
            'LORDS MOBILE', 'LIGHT OF THEL'
        ];
        
        foreach ($games as $game) {
            if (str_contains($brand, $game)) return true;
        }
        
        return false;
    }

    private function isBlacklisted($brand)
    {
        $brand = strtoupper($brand);
        
        $blacklist = [
            'VIETNAM', 'VIETNAM TOPUP', 'XOX', 'MEGAXUS', 'VOUCHER MEGAXUS',
            'SUN TELECOM', 'SUN', 'STARHUB', 'SMART', 'PHILIPPINES - SMART',
            'PHILIPPINES SMART', 'DOKU', 'GLOBE', 'LIKEE', 'NEX PARABOLA',
            'PARABOLA', 'WARP PLUS', 'WARP', 'CELCOM', 'DIGI', 'CHINA TOPUP',
            'MALAYSIA', 'SINGAPORE', 'PHILIPPINES', 'THAILAND',
        ];
        
        foreach ($blacklist as $blocked) {
            if (str_contains($brand, $blocked)) {
                return true;
            }
        }
        
        return false;
    }

    private function getDynamicLabel($type)
    {
        return match($type) {
            'pln' => 'ID Pelanggan / No Meter',
            'streaming', 'subscription' => 'Email / Nomor Akun',
            'ewallet' => 'Nomor HP E-Wallet',
            'voucher' => 'Voucher Code',
            default => 'Nomor HP Tujuan',
        };
    }

    private function normalizeBrandName($name)
    {
        return strtoupper(preg_replace('/[^A-Z0-9]/', '', trim($name)));
    }
}