<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Requests\Order\OrderRequest;
use App\Http\Resources\OrderResource;
use App\Http\Resources\PaymentResource;
use App\Models\Order;
use App\Services\OrderService;
use App\Support\ApiResponse;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use InvalidArgumentException;
use RuntimeException;

class OrderController extends Controller
{
    public function index()
    {
        Gate::authorize('viewAny', Order::class);

        $user = request()->user();

        $orders = Order::query()
            ->with(['product', 'producer', 'user'])
            ->when(! $user->hasRole('admin'), fn ($query) => $query->where('user_id', $user->id))
            ->get();

        return OrderResource::collection($orders);
    }

    public function store(OrderRequest $request, OrderService $orderService)
    {
        Gate::authorize('create', Order::class);

        try {
            $result = $orderService->place($request->user(), $request->validated());
        } catch (InvalidArgumentException|RuntimeException $exception) {
            return ApiResponse::response(message: $exception->getMessage(), status: 422);
        } catch (Exception $exception) {
            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        $orders = Order::query()
            ->with(['product', 'producer'])
            ->whereIn('id', $result['orders']->pluck('id'))
            ->get();

        $gatewayUrl = $result['gateway_url'] ?? null;

        return ApiResponse::response(
            data: [
                'orders' => OrderResource::collection($orders),
                'order' => new OrderResource($orders->first()),
                'payable' => $result['payable'],
                'payment_method' => $request->validated('payment_method'),
                'payment' => $result['payment']
                    ? new PaymentResource($result['payment']->loadMissing('user'))
                    : null,
                'gateway_url' => $gatewayUrl,
                'gateway' => $result['gateway'] ?? null,
            ],
            next: $gatewayUrl,
            message: 'سفارش با موفقیت ثبت شد.',
            status: 201,
        );
    }

    public function show(Order $order)
    {
        Gate::authorize('view', $order);

        return new OrderResource($order->load(['product', 'producer', 'user']));
    }

    public function update(Request $request, Order $order)
    {
        Gate::authorize('update', $order);

        try {
            $data = $request->only(['notes', 'status', 'delivery_address', 'delivery_date']);
            $data['updated_by'] = $request->user()->id;
            $order->update($data);
        } catch (Exception $exception) {
            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        return new OrderResource($order->fresh()->load(['product', 'producer', 'user']));
    }

    public function destroy(Order $order)
    {
        Gate::authorize('delete', $order);

        try {
            $order->delete();
        } catch (Exception $exception) {
            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        return ApiResponse::success(message: 'با موفقیت حذف شد');
    }
}
