<?php

namespace App\Http\Controllers\Api;

use App\Enums\ProductReservationStatus;
use App\Events\UserNotificationsUpdated;
use App\Models\Product;
use App\Models\ProductReservation;
use App\Notifications\ProductReservationRequested;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class CatalogProductReservationController extends Controller
{
    public function mine(Request $request): JsonResponse
    {
        $query = ProductReservation::query()
            ->where('customer_user_id', $request->user()->id)
            ->with([
                'product:id,name,unit_type,price,stock_quantity',
                'store:id,name,slug',
            ])
            ->orderByDesc('created_at');

        return response()->json($query->paginate(min($request->integer('per_page', 25), 50)));
    }

    public function store(Request $request, Product $product): JsonResponse
    {
        $product->load(['category:id,slug,supports_product_reservations', 'store:id,user_id,is_active,is_approved']);

        if (!$product->is_active) {
            return response()->json(['message' => 'Bu ürün şu anda listelenemiyor.'], 422);
        }

        $store = $product->store;
        if (!$store || !$store->is_active || !$store->is_approved) {
            return response()->json(['message' => 'Mağaza uygun değil.'], 422);
        }

        if (!$product->category?->supports_product_reservations) {
            return response()->json(['message' => 'Bu ürün için mağaza üzerinden ayırtma açılmamış.'], 422);
        }

        if ((int) $store->user_id === (int) $request->user()->id) {
            return response()->json(['message' => 'Kendi mağazanızdan rezervasyon oluşturamazsınız.'], 422);
        }

        $validated = $request->validate([
            'quantity' => 'required|integer|min:1|max:100000',
            'customer_note' => 'nullable|string|max:1000',
        ]);

        $reservation = ProductReservation::create([
            'store_id' => $product->store_id,
            'product_id' => $product->id,
            'customer_user_id' => $request->user()->id,
            'quantity' => $validated['quantity'],
            'status' => ProductReservationStatus::Pending,
            'customer_note' => $validated['customer_note'] ?? null,
        ]);

        $reservation->load(['product:id,name', 'store:id,name,user_id']);
        $store->unsetRelation('user');
        $owner = \App\Models\User::query()->find($store->user_id);

        if ($owner && $owner->notifications_enabled) {
            $owner->notify(new ProductReservationRequested($reservation));

            try {
                broadcast(new UserNotificationsUpdated(
                    userId: $owner->id,
                    type: 'notification',
                    notificationType: 'product_reservation_requested',
                    title: 'Yeni ürün rezervasyon talebi',
                    message: sprintf(
                        '%s ürünü için %s adet talep geldi.',
                        $product->name,
                        $reservation->quantity
                    ),
                    actionUrl: '/seller/product-reservations',
                ));
            } catch (\Throwable $e) {
                \Log::error('ProductReservationRequested broadcast error', ['error' => $e->getMessage()]);
            }
        }

        return response()->json([
            'message' => 'Rezervasyon talebiniz gönderildi.',
            'data' => $reservation,
        ], 201);
    }

    public function cancel(Request $request, ProductReservation $reservation): JsonResponse
    {
        if ($reservation->customer_user_id !== $request->user()->id) {
            return response()->json(['message' => 'Yetkisiz.'], 403);
        }

        if ($reservation->status !== ProductReservationStatus::Pending) {
            return response()->json(['message' => 'Sadece beklemedeki talepler iptal edilebilir.'], 422);
        }

        $reservation->update(['status' => ProductReservationStatus::Cancelled]);

        return response()->json([
            'message' => 'Talebiniz iptal edildi.',
            'data' => $reservation->fresh(['product:id,name', 'store:id,name,slug']),
        ]);
    }
}
