<?php

namespace App\Http\Controllers;

use App\Models\Category;
use App\Models\Announcement;
use App\Models\HomeSlider;
use App\Models\Product;
use App\Models\SiteSetting;
use App\Support\SeoMeta;
use Illuminate\Support\Str;
use Illuminate\View\View;

class StorefrontController extends Controller
{
    public function index(): View
    {
        $fallbackImage = SiteSetting::productFallbackImageUrl();

        $dbProducts = Product::query()
            ->with(['category', 'images'])
            ->where('is_active', true)
            ->whereHas('category', fn ($query) => $query->where('is_active', true))
            ->latest()
            ->get()
            ->map(function (Product $product) use ($fallbackImage): array {
                $compareAtPrice = $product->compareAtPrice();

                return [
                    'id' => $product->id,
                    'url' => route('storefront.products.show', $product),
                    'name' => $product->name,
                    'category' => $product->category->name,
                    'price' => $product->sellingPrice(),
                    'price_display' => SiteSetting::formatPrice($product->sellingPrice()),
                    'compare_price_display' => $compareAtPrice ? SiteSetting::formatPrice($compareAtPrice) : null,
                    'discount_percent' => $product->displayDiscountPercent(),
                    'stock' => $product->stock,
                    'rating' => (float) $product->rating,
                    'image' => $product->primaryImageUrl() ?: $fallbackImage,
                ];
            });

        $featuredProducts = Product::query()
            ->with(['category', 'images'])
            ->where('is_active', true)
            ->where('is_featured', true)
            ->whereHas('category', fn ($query) => $query->where('is_active', true))
            ->latest()
            ->take(8)
            ->get()
            ->map(fn (Product $product) => $this->productCard($product, $fallbackImage))
            ->all();

        $products = $dbProducts->isNotEmpty() ? $dbProducts->all() : [
            [
                'id' => null,
                'url' => null,
                'name' => 'AeroPods Pro',
                'category' => 'Electronics',
                'price' => 179,
                'price_display' => SiteSetting::formatPrice(179),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 86,
                'rating' => 4.8,
                'image' => 'https://images.unsplash.com/photo-1606220945770-b5b6c2c55bf1?auto=format&fit=crop&w=900&q=80',
            ],
            [
                'id' => null,
                'url' => null,
                'name' => 'Nomad Weekender',
                'category' => 'Fashion',
                'price' => 132,
                'price_display' => SiteSetting::formatPrice(132),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 42,
                'rating' => 4.6,
                'image' => 'https://images.unsplash.com/photo-1553062407-98eeb64c6a62?auto=format&fit=crop&w=900&q=80',
            ],
            [
                'id' => null,
                'url' => null,
                'name' => 'Oak Desk Lamp',
                'category' => 'Home',
                'price' => 84,
                'price_display' => SiteSetting::formatPrice(84),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 58,
                'rating' => 4.7,
                'image' => 'https://images.unsplash.com/photo-1507473885765-e6ed057f782c?auto=format&fit=crop&w=900&q=80',
            ],
            [
                'id' => null,
                'url' => null,
                'name' => 'Pulse Fitness Band',
                'category' => 'Fitness',
                'price' => 99,
                'price_display' => SiteSetting::formatPrice(99),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 74,
                'rating' => 4.5,
                'image' => 'https://images.unsplash.com/photo-1575311373937-040b8e1fd5b6?auto=format&fit=crop&w=900&q=80',
            ],
            [
                'id' => null,
                'url' => null,
                'name' => 'Stoneware Dinner Set',
                'category' => 'Home',
                'price' => 118,
                'price_display' => SiteSetting::formatPrice(118),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 35,
                'rating' => 4.9,
                'image' => 'https://images.unsplash.com/photo-1516223725307-6f76b9ec8742?auto=format&fit=crop&w=900&q=80',
            ],
            [
                'id' => null,
                'url' => null,
                'name' => 'Linen Field Jacket',
                'category' => 'Fashion',
                'price' => 148,
                'price_display' => SiteSetting::formatPrice(148),
                'compare_price_display' => null,
                'discount_percent' => 0,
                'stock' => 27,
                'rating' => 4.4,
                'image' => 'https://images.unsplash.com/photo-1523398002811-999ca8dec234?auto=format&fit=crop&w=900&q=80',
            ],
        ];

        $categories = Category::query()
            ->where('is_active', true)
            ->orderBy('name')
            ->pluck('name')
            ->prepend('All')
            ->all();

        $heroSlides = HomeSlider::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->latest()
            ->get()
            ->map(fn (HomeSlider $slider) => [
                'title' => $slider->title,
                'subtitle' => $slider->subtitle,
                'image' => $slider->imageUrl(),
                'url' => $slider->button_url ?: '#products',
                'button_text' => $slider->button_text ?: 'Shop now',
            ])
            ->values()
            ->all();

        if ($heroSlides === []) {
            $heroSlides = collect($products)
                ->take(4)
                ->map(fn (array $product) => [
                    'title' => $product['name'],
                    'subtitle' => "{$product['category']} - {$product['price_display']}",
                    'image' => $product['image'],
                    'url' => $product['url'] ?: '#products',
                    'button_text' => 'Shop now',
                ])
                ->values()
                ->all();
        }

        return view('storefront.home', [
            'categories' => count($categories) > 1 ? $categories : ['All', 'Electronics', 'Fashion', 'Home', 'Fitness'],
            'products' => $products,
            'featuredProducts' => $featuredProducts,
            'heroSlides' => $heroSlides,
            'announcement' => Announcement::query()->published()->latest()->first(),
            'seo' => SeoMeta::make('8Stores Marketplace'),
        ]);
    }

    public function category(Category $category): View
    {
        abort_if(! $category->is_active, 404);

        $fallbackImage = SiteSetting::productFallbackImageUrl();
        $products = Product::query()
            ->with(['category', 'images'])
            ->where('category_id', $category->id)
            ->where('is_active', true)
            ->latest()
            ->get()
            ->map(fn (Product $product) => $this->productCard($product, $fallbackImage))
            ->all();

        return view('storefront.category', [
            'category' => $category,
            'products' => $products,
            'seo' => SeoMeta::make(
                $category->meta_title ?: $category->name,
                $category->meta_description ?: $category->description,
                $category->ogImageUrl(),
            ),
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    private function productCard(Product $product, string $fallbackImage): array
    {
        $compareAtPrice = $product->compareAtPrice();

        return [
            'id' => $product->id,
            'url' => route('storefront.products.show', $product),
            'name' => $product->name,
            'category' => $product->category->name,
            'price' => $product->sellingPrice(),
            'price_display' => SiteSetting::formatPrice($product->sellingPrice()),
            'compare_price_display' => $compareAtPrice ? SiteSetting::formatPrice($compareAtPrice) : null,
            'discount_percent' => $product->displayDiscountPercent(),
            'stock' => $product->stock,
            'rating' => (float) $product->rating,
            'image' => $product->primaryImageUrl() ?: $fallbackImage,
        ];
    }

    public function show(Product $product): View
    {
        abort_if(! $product->is_active || ! $product->category?->is_active, 404);

        $product->load([
            'category',
            'images',
            'activeVariants',
            'reviews' => fn ($query) => $query->with('customer')->latest()->limit(20),
        ]);

        $reviewStats = $product->reviews()
            ->selectRaw('COUNT(*) as total_reviews, AVG(rating) as average_rating')
            ->first();

        $images = $product->images
            ->map(fn ($image) => $image->url())
            ->values()
            ->all();

        if ($images === []) {
            $images[] = SiteSetting::productFallbackImageUrl();
        }

        return view('storefront.products.show', [
            'product' => $product,
            'images' => $images,
            'reviews' => $product->reviews,
            'reviewCount' => (int) ($reviewStats->total_reviews ?? 0),
            'averageRating' => round((float) ($reviewStats->average_rating ?? 0), 1),
            'variants' => $product->activeVariants,
            'youtubeEmbedUrl' => $this->youtubeEmbedUrl($product->youtube_url),
            'seo' => SeoMeta::make(
                $product->meta_title ?: $product->name,
                $product->meta_description ?: $product->description,
                $product->ogImageUrl() ?: ($images[0] ?? null),
                'product',
            ),
        ]);
    }

    private function youtubeEmbedUrl(?string $url): ?string
    {
        if (! $url) {
            return null;
        }

        $host = parse_url($url, PHP_URL_HOST);
        $path = trim((string) parse_url($url, PHP_URL_PATH), '/');
        parse_str((string) parse_url($url, PHP_URL_QUERY), $query);

        $videoId = $query['v'] ?? null;

        if (! $videoId && Str::contains((string) $host, 'youtu.be')) {
            $videoId = $path;
        }

        if (! $videoId && Str::contains($path, 'shorts/')) {
            $videoId = Str::after($path, 'shorts/');
        }

        return $videoId ? 'https://www.youtube.com/embed/'.$videoId : null;
    }
}
