<?php

namespace App\Http\Controllers;

use App\Models\Announcement;
use App\Models\Banner;
use App\Models\Category;
use App\Models\OrderItem;
use App\ProductRepositoryInterface;
use App\Services\CacheService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class HomeController extends Controller
{
    public function __construct(
        protected CacheService $cacheService,
        protected ProductRepositoryInterface $productRepository
    ) {
    }

    public function index(): View
    {
        $featuredProducts = $this->rememberWithLock(CacheService::HOMEPAGE_FEATURED_PRODUCTS, 600, function () {
            return $this->productRepository->getFeatured(12);
        });

        $categories = Cache::remember(CacheService::HOMEPAGE_CATEGORIES, 600, function () {
            return Category::active()
                ->root()
                ->orderBy('sort_order')
                ->take(12) // Show more categories for grid
                ->get();
        });

        $banners = Cache::remember(CacheService::HOMEPAGE_BANNERS, 600, function () {
            return Banner::active()
                ->ordered()
                ->take(3)
                ->get();
        });

        $announcements = Cache::remember('homepage.announcements', 600, function () {
            return Announcement::active()
                ->ordered()
                ->get();
        });

        // Best Sellers - Products with most sales
        $bestSellers = $this->rememberWithLock(CacheService::HOMEPAGE_BEST_SELLERS, 600, function () {
            $topProductIds = OrderItem::select('product_id', DB::raw('SUM(qty) as total_sold'))
                ->groupBy('product_id')
                ->orderByDesc('total_sold')
                ->take(12)
                ->pluck('product_id');

            if ($topProductIds->isEmpty()) {
                // If no sales yet, show featured products as best sellers
                return $this->productRepository->getFeatured(12);
            }

            $products = \App\Models\Product::with(['category', 'unit', 'variants' => function($query) {
                    $query->where('is_active', true)->forWebsite();
                }])
                ->whereIn('id', $topProductIds)
                ->active()
                ->forWebsite()
                ->inStock()
                ->get()
                ->sortBy(function ($product) use ($topProductIds) {
                    return $topProductIds->search($product->id);
                })
                ->values();
            
            return $products;
        });

        // New Arrivals - Latest products
        $newArrivals = $this->rememberWithLock(CacheService::HOMEPAGE_NEW_ARRIVALS, 600, function () {
            return $this->productRepository->getNewArrivals(12);
        });

        // On Sale - Products with discount (mrp > price)
        $onSaleProducts = $this->rememberWithLock(CacheService::HOMEPAGE_ON_SALE, 600, function () {
            return $this->productRepository->getOnSale(12);
        });

        // Category-wise Products - Show at least 3 products per category
        $categoryWiseProducts = $this->rememberWithLock(CacheService::HOMEPAGE_CATEGORY_WISE_PRODUCTS, 600, function () {
            $rootCategories = Category::active()
                ->root()
                ->orderBy('sort_order')
                ->take(6) // Show products for top 6 categories
                ->get();
            
            // Optimize: Get all subcategories in one query
            $categoryIds = $rootCategories->pluck('id')->toArray();
            $allSubcategories = Category::whereIn('parent_id', $categoryIds)
                ->active()
                ->get()
                ->groupBy('parent_id');
            
            $categoryProducts = [];
            
            foreach ($rootCategories as $category) {
                // Get products for this category using repository
                $subCategoryIds = $allSubcategories->get($category->id, collect())->pluck('id')->toArray();
                $categoryIdsToQuery = array_merge([$category->id], $subCategoryIds);

                $categoryProductsPaginated = $this->productRepository->getByCategories($categoryIdsToQuery, [
                    'in_stock' => true,
                    'per_page' => 6
                ]);
                $products = $categoryProductsPaginated->items(); // Get items from paginator
                
                if (count($products) >= 6) {
                    $categoryProducts[$category->id] = [
                        'category' => $category,
                        'products' => collect($products)->take(6), // Show 6 products
                        'hasMore' => count($products) > 6
                    ];
                }
            }
            
            return $categoryProducts;
        });

        return view('home', compact(
            'featuredProducts',
            'categories',
            'banners',
            'bestSellers',
            'newArrivals',
            'onSaleProducts',
            'categoryWiseProducts',
            'announcements'
        ));
    }

    /**
     * Get or set cache with a lock to prevent stampede when many requests repopulate the same key.
     */
    private function rememberWithLock(string $key, int $ttlSeconds, callable $callback): mixed
    {
        $cached = Cache::get($key);
        if ($cached !== null) {
            return $cached;
        }
        $lock = Cache::lock($key . '.lock', 15);
        return $lock->block(10, function () use ($key, $ttlSeconds, $callback) {
            $cached = Cache::get($key);
            if ($cached !== null) {
                return $cached;
            }
            $data = $callback();
            Cache::put($key, $data, $ttlSeconds);
            return $data;
        });
    }
}
