<?php

declare(strict_types=1);

namespace App\Services\AiAssistant\Tools;

use App\Models\Product;
use Illuminate\Support\Str;

class ProductTools
{
    public function search(array $params): string
    {
        $query = $params['query'] ?? '';
        $categoryId = $params['category_id'] ?? null;
        $minPrice = $params['min_price'] ?? null;
        $maxPrice = $params['max_price'] ?? null;
        $limit = min($params['limit'] ?? 10, 50);

        $products = Product::query()
            ->when($query, fn ($q) => $q->where(function ($subQ) use ($query) {
                $subQ->where('name_en', 'like', "%{$query}%")
                    ->orWhere('name_ar', 'like', "%{$query}%")
                    ->orWhere('description_en', 'like', "%{$query}%")
                    ->orWhere('description_ar', 'like', "%{$query}%");
            }))
            ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
            ->when($minPrice, fn ($q) => $q->where('price', '>=', $minPrice))
            ->when($maxPrice, fn ($q) => $q->where('price', '<=', $maxPrice))
            ->with('category')
            ->limit($limit)
            ->get();

        if ($products->isEmpty()) {
            return 'No products found matching your criteria. Try adjusting your search terms or filters.';
        }

        $response = "Found {$products->count()} product(s):\n\n";

        foreach ($products as $product) {
            $response .= $this->formatProduct($product);
        }

        return $response;
    }

    public function getDetails(int $productId): string
    {
        $product = Product::with('category')->find($productId);

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

        $response = "**{$product->name_en}**\n\n";
        $response .= '- **Price**: $'.number_format($product->price, 2);

        if ($product->discount_price) {
            $response .= ' (Sale: $'.number_format($product->discount_price, 2).')';
        }

        $response .= "\n";
        $response .= '- **Category**: '.($product->category?->name_en ?? 'N/A')."\n";
        $response .= '- **Rating**: '.$product->positive_feedback."% positive\n";
        $response .= '- **Sales**: '.$product->sales_180day." in last 180 days\n";

        if ($product->discount > 0) {
            $response .= "- **Discount**: {$product->discount}% off\n";
        }

        if ($product->code_name) {
            $response .= "- **Promo Code**: {$product->code_name} (Save $".number_format($product->code_value, 2).")\n";
        }

        if ($product->description_en) {
            $response .= "\n**Description**: ".Str::limit($product->description_en, 200)."\n";
        }

        return $response;
    }

    public function compare(array $productIds): string
    {
        if (count($productIds) < 2) {
            return 'Please provide at least 2 product IDs to compare.';
        }

        if (count($productIds) > 5) {
            return 'I can compare up to 5 products at a time.';
        }

        $products = Product::with('category')
            ->whereIn('id', array_slice($productIds, 0, 5))
            ->get();

        if ($products->count() < 2) {
            return 'Could not find enough products to compare. Please check the product IDs.';
        }

        $response = "**Comparing {$products->count()} products**\n\n";

        $response .= "| Product | Price | Discount | Rating | Sales | Category |\n";
        $response .= "|---------|-------|----------|--------|-------|----------|\n";

        foreach ($products as $p) {
            $price = $p->discount_price ?? $p->price;
            $discount = $p->discount > 0 ? "{$p->discount}%" : '-';
            $response .= "| {$p->name_en} | $".number_format($price, 2)." | {$discount} | {$p->positive_feedback}% | {$p->sales_180day} | ".($p->category?->name_en ?? '-')." |\n";
        }

        $response .= "\n**Key Insights**:\n\n";

        $bestPrice = $products->sortBy(fn ($p) => $p->discount_price ?? $p->price)->first();
        $response .= "- **Best Price**: {$bestPrice->name_en} at $".number_format($bestPrice->discount_price ?? $bestPrice->price, 2)."\n";

        $topRated = $products->sortByDesc('positive_feedback')->first();
        $response .= "- **Highest Rated**: {$topRated->name_en} ({$topRated->positive_feedback}% positive)\n";

        $bestDeal = $products->sortByDesc('discount')->first();
        if ($bestDeal->discount > 0) {
            $response .= "- **Best Deal**: {$bestDeal->name_en} ({$bestDeal->discount}% off)\n";
        }

        return $response;
    }

    protected function formatProduct(Product $product): string
    {
        $line = "- **{$product->name_en}** (ID: {$product->id})\n";
        $line .= '  - Price: $'.number_format($product->price, 2);

        if ($product->discount_price) {
            $line .= ' ~~$'.number_format($product->price, 2)."~~ ({$product->discount}% off)";
        }

        $line .= "\n";
        $line .= "  - Rating: {$product->positive_feedback}% positive";

        if ($product->category) {
            $line .= " | Category: {$product->category->name_en}";
        }

        $line .= "\n";

        if ($product->code_name) {
            $line .= "  - Promo Code: {$product->code_name} (Save $".number_format($product->code_value, 2).")\n";
        }

        $line .= "\n";

        return $line;
    }
}
