<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Product;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class RecommendationController extends Controller
{
    public function getRecommendations(Request $request)
    {
        $user = auth()->user();
        $company = $user->company ?? null;

        $recommendations = [];

        if ($company) {
            $purchaseHistory = $this->getPurchaseBasedRecommendations($company->id);
            $recommendations = array_merge($recommendations, $purchaseHistory);
        }

        if ($request->has('category_id')) {
            $categoryBased = $this->getCategoryBasedRecommendations($request->category_id);
            $recommendations = array_merge($recommendations, $categoryBased);
        }

        if ($request->has('product_id')) {
            $similarProducts = $this->getSimilarProducts($request->product_id);
            $recommendations = array_merge($recommendations, $similarProducts);
        }

        $popularProducts = $this->getPopularProducts();
        $recommendations = array_merge($recommendations, $popularProducts);

        $uniqueRecommendations = collect($recommendations)
            ->unique('id')
            ->take($request->get('limit', 12))
            ->values();

        return response()->json([
            'recommendations' => $uniqueRecommendations,
            'ai_insights' => $this->generateAIInsights($uniqueRecommendations, $company),
        ]);
    }

    private function getPurchaseBasedRecommendations($companyId)
    {
        $purchasedCategoryIds = OrderItem::whereHas('order', function ($query) use ($companyId) {
            $query->where('company_id', $companyId);
        })
        ->join('products', 'order_items.product_id', '=', 'products.id')
        ->pluck('products.category_id')
        ->unique()
        ->toArray();

        if (empty($purchasedCategoryIds)) {
            return [];
        }

        $purchasedProductIds = OrderItem::whereHas('order', function ($query) use ($companyId) {
            $query->where('company_id', $companyId);
        })
        ->pluck('product_id')
        ->toArray();

        return Product::whereIn('category_id', $purchasedCategoryIds)
            ->whereNotIn('id', $purchasedProductIds)
            ->where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->with(['supplier:id,company_name', 'category:id,name'])
            ->orderBy('order_count', 'desc')
            ->limit(6)
            ->get()
            ->map(function ($product) {
                $product->recommendation_reason = 'Based on your purchase history';
                return $product;
            })
            ->toArray();
    }

    private function getCategoryBasedRecommendations($categoryId)
    {
        return Product::where('category_id', $categoryId)
            ->where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->with(['supplier:id,company_name', 'category:id,name'])
            ->orderBy('rating', 'desc')
            ->orderBy('order_count', 'desc')
            ->limit(6)
            ->get()
            ->map(function ($product) {
                $product->recommendation_reason = 'Top rated in this category';
                return $product;
            })
            ->toArray();
    }

    private function getSimilarProducts($productId)
    {
        $product = Product::find($productId);

        if (!$product) {
            return [];
        }

        $query = Product::where('id', '!=', $productId)
            ->where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->with(['supplier:id,company_name', 'category:id,name']);

        if ($product->category_id) {
            $query->where('category_id', $product->category_id);
        }

        $priceRange = $product->price * 0.3;
        $query->whereBetween('price', [
            $product->price - $priceRange,
            $product->price + $priceRange
        ]);

        return $query->orderBy('rating', 'desc')
            ->limit(6)
            ->get()
            ->map(function ($p) {
                $p->recommendation_reason = 'Similar product';
                return $p;
            })
            ->toArray();
    }

    private function getPopularProducts()
    {
        return Product::where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->with(['supplier:id,company_name', 'category:id,name'])
            ->orderBy('order_count', 'desc')
            ->orderBy('view_count', 'desc')
            ->limit(6)
            ->get()
            ->map(function ($product) {
                $product->recommendation_reason = 'Popular choice';
                return $product;
            })
            ->toArray();
    }

    private function generateAIInsights($recommendations, $company)
    {
        $insights = [];

        if ($recommendations->count() > 0) {
            $avgPrice = $recommendations->avg('price');
            $insights[] = [
                'type' => 'price_insight',
                'message' => "Average price of recommended products: R" . number_format($avgPrice, 2),
            ];

            $categories = $recommendations->pluck('category.name')->unique()->filter()->values();
            if ($categories->count() > 0) {
                $insights[] = [
                    'type' => 'category_insight',
                    'message' => "Recommendations span " . $categories->count() . " categories: " . $categories->implode(', '),
                ];
            }

            $topRated = $recommendations->where('rating', '>=', 4)->count();
            if ($topRated > 0) {
                $insights[] = [
                    'type' => 'quality_insight',
                    'message' => "{$topRated} products have ratings of 4 stars or higher",
                ];
            }
        }

        if ($company) {
            $monthlySpend = Order::where('company_id', $company->id)
                ->where('payment_status', 'paid')
                ->whereMonth('created_at', now()->month)
                ->sum('total_amount');

            if ($monthlySpend > 0) {
                $insights[] = [
                    'type' => 'spending_insight',
                    'message' => "Your spending this month: R" . number_format($monthlySpend, 2),
                ];
            }
        }

        return $insights;
    }

    public function priceComparison(Request $request)
    {
        $searchTerm = $request->get('search', '');

        if (empty($searchTerm)) {
            return response()->json(['error' => 'Search term required'], 422);
        }

        $products = Product::where('is_active', true)
            ->search($searchTerm)
            ->with(['supplier:id,company_name,is_verified,rating,delivery_self,delivery_platform,delivery_collection'])
            ->orderBy('price', 'asc')
            ->get();

        if ($products->isEmpty()) {
            return response()->json([
                'search_term' => $searchTerm,
                'products' => [],
                'comparison' => null,
                'ai_recommendation' => 'No products found matching your search. Try different keywords.',
            ]);
        }

        $prices = $products->pluck('price');
        $lowestPrice = $prices->min();
        $highestPrice = $prices->max();
        $avgPrice = $prices->avg();
        $priceDifference = $highestPrice - $lowestPrice;
        $savingsPercent = $highestPrice > 0 ? round(($priceDifference / $highestPrice) * 100, 1) : 0;

        $bestValue = $products->sortByDesc(function ($product) {
            $ratingScore = $product->rating * 20;
            $priceScore = 100 - (($product->price / $products->max('price')) * 100);
            $verifiedBonus = $product->supplier->is_verified ? 10 : 0;
            return $ratingScore + $priceScore + $verifiedBonus;
        })->first();

        $aiRecommendation = $this->generatePriceComparisonAI($products, $bestValue, $savingsPercent);

        return response()->json([
            'search_term' => $searchTerm,
            'products' => $products,
            'comparison' => [
                'lowest_price' => $lowestPrice,
                'highest_price' => $highestPrice,
                'average_price' => round($avgPrice, 2),
                'price_difference' => $priceDifference,
                'potential_savings_percent' => $savingsPercent,
                'total_suppliers' => $products->pluck('supplier_id')->unique()->count(),
                'total_products' => $products->count(),
            ],
            'best_value_product' => $bestValue,
            'ai_recommendation' => $aiRecommendation,
        ]);
    }

    private function generatePriceComparisonAI($products, $bestValue, $savingsPercent)
    {
        $recommendations = [];

        if ($savingsPercent > 20) {
            $recommendations[] = "Significant price variation detected ({$savingsPercent}% difference). Compare carefully before purchasing.";
        }

        if ($bestValue) {
            $recommendations[] = "Best value: {$bestValue->name} from {$bestValue->supplier->company_name} at R" . number_format($bestValue->price, 2);
            
            if ($bestValue->supplier->is_verified) {
                $recommendations[] = "This supplier is verified, ensuring reliability.";
            }

            if ($bestValue->rating >= 4) {
                $recommendations[] = "This product has excellent ratings ({$bestValue->rating}/5 stars).";
            }
        }

        $verifiedProducts = $products->filter(function ($p) {
            return $p->supplier->is_verified;
        });

        if ($verifiedProducts->count() > 0 && $verifiedProducts->count() < $products->count()) {
            $recommendations[] = "{$verifiedProducts->count()} out of {$products->count()} products are from verified suppliers.";
        }

        return implode(' ', $recommendations);
    }

    public function trendingProducts(Request $request)
    {
        $trending = Product::where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->with(['supplier:id,company_name', 'category:id,name'])
            ->orderByRaw('(order_count * 2 + view_count) DESC')
            ->limit($request->get('limit', 12))
            ->get();

        return response()->json([
            'trending' => $trending,
            'updated_at' => now()->toISOString(),
        ]);
    }

    public function dealOfTheDay()
    {
        $deal = Product::where('is_active', true)
            ->where('stock_quantity', '>', 0)
            ->whereNotNull('compare_price')
            ->whereRaw('compare_price > price')
            ->with(['supplier:id,company_name', 'category:id,name'])
            ->orderByRaw('((compare_price - price) / compare_price) DESC')
            ->first();

        if (!$deal) {
            $deal = Product::where('is_active', true)
                ->where('is_featured', true)
                ->where('stock_quantity', '>', 0)
                ->with(['supplier:id,company_name', 'category:id,name'])
                ->inRandomOrder()
                ->first();
        }

        return response()->json([
            'deal' => $deal,
            'expires_at' => now()->endOfDay()->toISOString(),
        ]);
    }
}
