<?php

namespace App\Services;

use App\Models\Product;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class DealFinderService
{
    public function findBestDeals(?int $categoryId = null, int $limit = 10): Collection
    {
        return Product::query()
            ->when($categoryId, fn ($q) => $q->where('category_id', $categoryId))
            ->whereHasDiscount()
            ->with('category')
            ->orderByDiscount('desc')
            ->orderBy('sales_180day', 'desc')
            ->limit($limit)
            ->get();
    }

    public function findPriceDrops(int $limit = 10): Collection
    {
        return Product::query()
            ->whereNotNull('discount_price')
            ->where('discount_price', '<', DB::raw('price'))
            ->with('category')
            ->orderByDesc('discount')
            ->orderBy('sales_180day', 'desc')
            ->limit($limit)
            ->get();
    }

    public function findCouponDeals(int $limit = 10): Collection
    {
        $now = now();

        return Product::query()
            ->whereNotNull('code_name')
            ->where('code_quantity', '>', 0)
            ->where(function ($query) use ($now) {
                $query->whereNull('code_end_time')
                    ->orWhere('code_end_time', '>', $now);
            })
            ->with('category')
            ->orderByDesc('code_value')
            ->orderByDiscount('desc')
            ->limit($limit)
            ->get();
    }

    public function calculateSavings(Product $product): array
    {
        $savings = [
            'has_discount' => false,
            'original_price' => (float) $product->price,
            'discounted_price' => null,
            'discount_amount' => 0,
            'discount_percentage' => 0,
            'currency' => $product->currency,
            'has_promo_code' => false,
            'promo_code' => null,
            'promo_value' => 0,
            'total_potential_savings' => 0,
        ];

        if ($product->discount_price && $product->discount_price < $product->price) {
            $savings['has_discount'] = true;
            $savings['discounted_price'] = (float) $product->discount_price;
            $savings['discount_amount'] = (float) ($product->price - $product->discount_price);
            $savings['discount_percentage'] = round(($product->price - $product->discount_price) / $product->price * 100, 2);
        }

        if ($product->code_name) {
            $savings['has_promo_code'] = true;
            $savings['promo_code'] = $product->code_name;
            $savings['promo_value'] = (float) $product->code_value;
            $savings['total_potential_savings'] = $savings['discount_amount'] + $savings['promo_value'];
        }

        return $savings;
    }

    public function findBestValueDeals(int $limit = 10): Collection
    {
        return Product::query()
            ->whereHasDiscount()
            ->where('positive_feedback', '>', 70)
            ->with('category')
            ->orderBy('positive_feedback', 'desc')
            ->orderByDiscount('desc')
            ->limit($limit)
            ->get();
    }

    public function getCategoryDealsSummary(): array
    {
        return Product::query()
            ->select('category_id')
            ->selectRaw('COUNT(*) as deal_count')
            ->selectRaw('AVG((price - COALESCE(discount_price, price)) / price * 100) as avg_discount')
            ->selectRaw('MAX((price - COALESCE(discount_price, price)) / price * 100) as max_discount')
            ->whereHasDiscount()
            ->with('category')
            ->groupBy('category_id')
            ->orderByDesc('deal_count')
            ->get()
            ->map(function ($item) {
                return [
                    'category_id' => $item->category_id,
                    'category_name' => $item->category?->name_en ?? $item->category?->name_ar,
                    'deal_count' => $item->deal_count,
                    'avg_discount' => number_format($item->avg_discount, 2),
                    'max_discount' => number_format($item->max_discount, 2),
                ];
            })
            ->toArray();
    }

    public function findFlashDeals(int $limit = 10): Collection
    {
        $threeDaysFromNow = now()->addDays(3);

        return Product::query()
            ->whereHasDiscount()
            ->where(function ($query) use ($threeDaysFromNow) {
                $query->whereNull('code_end_time')
                    ->orWhere('code_end_time', '<=', $threeDaysFromNow);
            })
            ->with('category')
            ->orderByDiscount('desc')
            ->orderBy('sales_180day', 'desc')
            ->limit($limit)
            ->get();
    }
}
