<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Mail\BackInStock;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\StockNotification;
use App\Services\MailService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class StockNotificationController extends Controller
{
    public function __construct(private MailService $mailService) {}

    /**
     * POST /stock-notify
     * Subscribe an email to be notified when a product/variant is back in stock.
     */
    public function subscribe(Request $request): JsonResponse
    {
        $request->validate([
            'email'      => 'required|email',
            'product_id' => 'required|integer|exists:products,id',
            'variant_id' => 'nullable|integer|exists:product_variants,id',
        ]);

        $already = StockNotification::where('email', $request->email)
            ->where('product_id', $request->product_id)
            ->where('variant_id', $request->variant_id)
            ->whereNull('notified_at')
            ->exists();

        if ($already) {
            return response()->json(['message' => 'You are already on the notification list.']);
        }

        StockNotification::create([
            'email'      => $request->email,
            'product_id' => $request->product_id,
            'variant_id' => $request->variant_id,
        ]);

        return response()->json(['message' => "We'll email you when this product is back in stock."]);
    }

    /**
     * GET /admin/stock-notifications
     * List all pending notifications (admin only).
     */
    public function index(): JsonResponse
    {
        $notifications = StockNotification::with(['product', 'variant'])
            ->whereNull('notified_at')
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(fn($n) => [
                'id'           => $n->id,
                'email'        => $n->email,
                'product_name' => $n->product?->name,
                'variant_name' => $n->variant?->name,
                'product_id'   => $n->product_id,
                'variant_id'   => $n->variant_id,
                'created_at'   => $n->created_at,
            ]);

        return response()->json(['data' => $notifications]);
    }

    /**
     * POST /admin/stock-notifications/trigger/{productId}
     * Manually trigger back-in-stock emails for a product.
     */
    public function trigger(Request $request, int $productId): JsonResponse
    {
        $product = Product::findOrFail($productId);

        $variantId = $request->variant_id ?? null;

        $query = StockNotification::where('product_id', $productId)
            ->whereNull('notified_at');

        if ($variantId) {
            $query->where('variant_id', $variantId);
        }

        $notifications = $query->get();
        $sent = 0;

        foreach ($notifications as $notification) {
            try {
                Mail::to($notification->email)->send(new BackInStock($product, $notification->variant));
                $notification->update(['notified_at' => now()]);
                $sent++;
            } catch (\Throwable $e) {
                \Illuminate\Support\Facades\Log::error("BackInStock mail failed: " . $e->getMessage());
            }
        }

        return response()->json([
            'message' => "{$sent} notification(s) sent.",
            'sent'    => $sent,
        ]);
    }

    /**
     * Auto-trigger notifications when stock is updated above 0.
     * Called internally from inventory update flow.
     */
    public static function autoTrigger(int $productId, ?int $variantId = null): void
    {
        $product = Product::find($productId);
        if (!$product) return;

        $variant = $variantId ? ProductVariant::find($variantId) : null;

        $notifications = StockNotification::where('product_id', $productId)
            ->where(function ($q) use ($variantId) {
                if ($variantId) {
                    $q->where('variant_id', $variantId)->orWhereNull('variant_id');
                } else {
                    $q->whereNull('variant_id');
                }
            })
            ->whereNull('notified_at')
            ->get();

        foreach ($notifications as $notification) {
            try {
                Mail::to($notification->email)->send(new BackInStock($product, $variant));
                $notification->update(['notified_at' => now()]);
            } catch (\Throwable $e) {
                \Illuminate\Support\Facades\Log::error("BackInStock auto mail failed: " . $e->getMessage());
            }
        }
    }
}
