<?php

namespace App\Http\Controllers;

use App\Exceptions\PaymentFailedException;
use App\Exceptions\PaymentException;
use App\Exceptions\PaymentMissingDataException;
use App\Http\Requests\PayServicePackageRequest;
use App\Http\Requests\PaymentRequest;
use App\Http\Resources\PaymentResource;
use App\Models\ServicePackage;
use App\Services\PaymentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;

class PaymentController extends Controller
{
    public function __construct(
        protected PaymentService $service,
    ) {}

    public function index(): JsonResponse
    {
        $items = $this->service->getAll();

        return $this->successResponse(payload: PaymentResource::collection($items));
    }

    public function store(PaymentRequest $request): JsonResponse
    {
        $item = $this->service->create($request->validated());

        return $this->successResponse(
            payload: new PaymentResource($item),
            message: $item->status->message(),
            code:    201,
        );
    }

    public function show(int $id): JsonResponse
    {
        $item = $this->service->findById($id);

        return $this->successResponse(payload: new PaymentResource($item));
    }

    public function update(PaymentRequest $request, int $id): JsonResponse
    {
        $item = $this->service->update($id, $request->validated());

        return $this->successResponse(payload: new PaymentResource($item), message: __('messages.updated'));
    }

    public function destroy(int $id): JsonResponse
    {
        $this->service->delete($id);

        return $this->successResponse(message: __('messages.deleted'), code: 204);
    }

    //

    public function payServicePackage(PayServicePackageRequest $request, int $servicePackageId): JsonResponse
    {
        $validated = $request->validated();

        try {
            $item = $this->service->payServicePackage(
                servicePackageId:      $servicePackageId,
                paymentMethod:         data_get($validated, 'payment_method'),
                clientPaymentMethodId: data_get($validated, 'client_payment_method_id'),

                options: [
                    'phone'   => data_get($validated, 'phone'),
                    'card_id' => data_get($validated, 'card_id'),
                ],
            );
        } catch (PaymentMissingDataException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'error'   => 'missing_payment_data',
            ], 422);
        } catch (PaymentFailedException) {
            return $this->errorResponse(message: __('messages.payment_not_confirmed'), code: 422);
        } catch (PaymentException) {
            return $this->errorResponse(message: __('messages.payment_error'), code: 422);
        }

        return $this->successResponse(
            payload: new PaymentResource($item),
            message: $item->status->message(),
            code:    201,
        );
    }

    //

    public function getServicePackagePix(ServicePackage $servicePackage): JsonResponse
    {
        if ($servicePackage->client?->user_id !== Auth::id()) {
            abort(403);
        }

        try {
            $item = $this->service->getOrCreateServicePackagePixPayment($servicePackage);
        } catch (PaymentMissingDataException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'error'   => 'missing_payment_data',
            ], 422);
        }

        return $this->successResponse(payload: new PaymentResource($item));
    }

    public function platformFees(): JsonResponse
    {
        return $this->successResponse(payload: $this->service->platformFees());
    }

}
