<?php

declare(strict_types=1);

namespace App\Services\AiAssistant\Tools;

use App\Models\Product;
use App\Services\AiAssistant\AiComponentRenderer;
use App\Services\AiAssistant\StructuredResponse;

class DiscoveryTools
{
    public function __construct(
        protected AiComponentRenderer $renderer
    ) {}

    public function getBudgetFinder(string $tier, ?int $categoryId = null, ?int $limit = 10): StructuredResponse
    {
        $limit = min($limit ?? 10, 50);

        $ranges = [
            'budget' => ['min' => 0, 'max' => 50],
            'mid' => ['min' => 50, 'max' => 200],
            'premium' => ['min' => 200, 'max' => 1000],
            'luxury' => ['min' => 1000, 'max' => 999999],
        ];

        $range = $ranges[$tier] ?? $ranges['mid'];

        // Use effective price (discount_price when available, otherwise price)
        $products = Product::query()
            ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
            ->whereRaw('COALESCE(discount_price, price) >= ?', [$range['min']])
            ->whereRaw('COALESCE(discount_price, price) < ?', [$range['max']])
            ->with('category')
            ->orderByRaw('COALESCE(discount_price, price) ASC')
            ->limit($limit)
            ->get();

        // If no products found in the specified range, fall back to showing the absolute cheapest products
        if ($products->isEmpty()) {
            $products = Product::query()
                ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
                ->with('category')
                ->orderByRaw('COALESCE(discount_price, price) ASC')
                ->limit($limit)
                ->get();

            if ($products->isEmpty()) {
                return StructuredResponse::fromText(
                    $categoryId
                        ? 'No products found in this category.'
                        : 'No products available at the moment.'
                );
            }

            // Show the actual cheapest products available
            $text = "**🏷️ Cheapest Products Available**\n\n";
            $text .= "Note: No products under \${$range['max']}. Here are the lowest-priced products we have:\n\n";

            foreach ($products as $product) {
                $effectivePrice = $product->discount_price ?? $product->price;
                $text .= "- **{$product->name_en}** (ID: {$product->id}) - \${$effectivePrice}";
                if ($product->discount_price) {
                    $text .= " ~~\${$product->price}~~ ({$product->discount}% off)";
                }
                $text .= "\n";
            }

            $html = $this->renderer->productGrid($products, 'Cheapest Available', '💰 Lowest Prices');

            return StructuredResponse::withHtml($text, $html, [
                'tier' => $tier,
                'fallback' => true,
            ]);
        }

        $tierLabel = ucfirst($tier);
        $text = "**{$tierLabel} Picks (\${$range['min']} - \${$range['max']})**\n\n";

        foreach ($products as $product) {
            $effectivePrice = $product->discount_price ?? $product->price;
            $text .= "- **{$product->name_en}** (ID: {$product->id}) - \${$effectivePrice}";
            if ($product->discount_price) {
                $text .= " ~~\${$product->price}~~ ({$product->discount}% off)";
            }
            $text .= "\n";
        }

        $badge = match ($tier) {
            'budget' => '💰 Budget',
            'mid' => '⚖️ Mid-Range',
            'premium' => '✨ Premium',
            'luxury' => '💎 Luxury',
            default => null,
        };

        $html = $this->renderer->productGrid($products, "{$tierLabel} Picks", $badge);

        return StructuredResponse::withHtml($text, $html, [
            'tier' => $tier,
            'range' => $range,
        ]);
    }

    public function getTrendingProducts(?int $limit = 10): StructuredResponse
    {
        $limit = min($limit ?? 10, 50);

        // Trending based on recent sales + high rating
        $products = Product::query()
            ->where('sales_180day', '>', 10)
            ->where('positive_feedback', '>', 80)
            ->with('category')
            ->orderByRaw('(sales_180day * positive_feedback / 100) DESC')
            ->limit($limit)
            ->get();

        if ($products->isEmpty()) {
            return StructuredResponse::fromText(
                'No trending products found at the moment.'
            );
        }

        $text = "**🔥 Trending Products**\n\n";

        foreach ($products as $index => $product) {
            $text .= ($index + 1).". **{$product->name_en}** (ID: {$product->id})\n";
            $text .= "   - {$product->sales_180day} sales | {$product->positive_feedback}% rating\n";
        }

        $html = $this->renderer->productGrid(
            $products,
            'Trending Products',
            '🔥 Hot'
        );

        return StructuredResponse::withHtml($text, $html, [
            'count' => $products->count(),
        ]);
    }

    public function getSimilarProducts(int $productId, ?int $limit = 5): StructuredResponse
    {
        $limit = min($limit ?? 5, 20);

        $product = Product::with('category')->find($productId);

        if (! $product) {
            return StructuredResponse::fromText("Product with ID {$productId} not found.");
        }

        // Find similar products in the same category, sorted by price proximity
        $products = Product::query()
            ->where('id', '!=', $productId)
            ->when($product->category_id, fn ($q) => $q->where('category_id', $product->category_id))
            ->with('category')
            ->orderByRaw('ABS(price - ?) ASC', [$product->price])
            ->limit($limit)
            ->get();

        if ($products->isEmpty()) {
            return StructuredResponse::fromText(
                "No similar products found for {$product->name_en}."
            );
        }

        $text = "**Products similar to '{$product->name_en}'**\n\n";

        foreach ($products as $similar) {
            $priceDiff = abs((float) $similar->price - (float) $product->price);
            $text .= "- **{$similar->name_en}** (ID: {$similar->id})\n";
            $text .= "   - \${$similar->price} (";
            if ((float) $similar->price > (float) $product->price) {
                $text .= '+$'.number_format($priceDiff, 2);
            } else {
                $text .= '-$'.number_format($priceDiff, 2);
            }
            $text .= ")\n";
        }

        $html = $this->renderer->productGrid(
            $products,
            "Similar to '{$product->name_en}'"
        );

        return StructuredResponse::withHtml($text, $html, [
            'base_product_id' => $productId,
            'similar_count' => $products->count(),
        ]);
    }

    public function getNewArrivals(?int $categoryId = null, ?int $limit = 10): StructuredResponse
    {
        $limit = min($limit ?? 10, 50);

        // Assuming newer products have higher IDs or were created recently
        $products = Product::query()
            ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
            ->with('category')
            ->orderBy('id', 'desc')
            ->limit($limit)
            ->get();

        if ($products->isEmpty()) {
            return StructuredResponse::fromText('No new arrivals found.');
        }

        $text = "**✨ New Arrivals**\n\n";

        foreach ($products as $product) {
            $text .= "- **{$product->name_en}** (ID: {$product->id})\n";
            $text .= "   - \${$product->price} | {$product->positive_feedback}% rating\n";
        }

        $html = $this->renderer->productGrid(
            $products,
            'New Arrivals',
            '✨ New'
        );

        return StructuredResponse::withHtml($text, $html, [
            'count' => $products->count(),
        ]);
    }

    public function getTopRated(?int $categoryId = null, ?int $limit = 10): StructuredResponse
    {
        $limit = min($limit ?? 10, 50);

        $products = Product::query()
            ->where('positive_feedback', '>=', 90)
            ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
            ->with('category')
            ->orderBy('positive_feedback', 'desc')
            ->orderBy('sales_180day', 'desc')
            ->limit($limit)
            ->get();

        if ($products->isEmpty()) {
            return StructuredResponse::fromText(
                'No top-rated products found (90%+ rating).'
            );
        }

        $text = "**⭐ Top Rated Products (90%+ rating)**\n\n";

        foreach ($products as $index => $product) {
            $text .= ($index + 1).". **{$product->name_en}** (ID: {$product->id})\n";
            $text .= "   - {$product->positive_feedback}% positive | \${$product->price}\n";
        }

        $html = $this->renderer->productGrid(
            $products,
            'Top Rated',
            '⭐ Best'
        );

        return StructuredResponse::withHtml($text, $html, [
            'count' => $products->count(),
        ]);
    }
}
