<?php

declare(strict_types=1);

namespace App\Http\Controllers\Wallet;

use App\Http\Controllers\Controller;
use App\Http\Requests\Wallet\StoreBankCardRequest;
use App\Http\Requests\Wallet\UpdateBankCardRequest;
use App\Http\Resources\BankCardResource;
use App\Models\BankCard;
use App\Support\ApiResponse;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;

class BankCardController extends Controller
{
    public function index(Request $request)
    {
        Gate::authorize('viewAny', BankCard::class);

        $query = BankCard::query()
            ->where('user_id', $request->user()->id)
            ->orderByDesc('is_default')
            ->latest();

        if ($request->filled('status')) {
            $query->where('status', $request->string('status'));
        }

        $perPage = min($request->integer('per_page', 15), 50);

        return BankCardResource::collection(
            $request->boolean('noPaginate') ? $query->get() : $query->paginate($perPage)
        );
    }

    public function store(StoreBankCardRequest $request)
    {
        Gate::authorize('create', BankCard::class);

        $user = $request->user();

        try {
            DB::beginTransaction();

            $isFirst = ! BankCard::query()->where('user_id', $user->id)->exists();
            $makeDefault = $request->boolean('is_default', $isFirst);

            $card = BankCard::create([
                'user_id' => $user->id,
                'bank_name' => $request->input('bank_name'),
                'card_number' => $request->input('card_number'),
                'shaba' => $request->string('shaba'),
                'account_holder_name' => $request->string('account_holder_name'),
                'is_default' => false,
                'status' => BankCard::STATUS_ACTIVE,
            ]);

            if ($makeDefault) {
                $card->markAsDefault();
            }

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();

            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        return ApiResponse::created(
            new BankCardResource($card->fresh()),
            'کارت بانکی ثبت شد.'
        );
    }

    public function show(Request $request, BankCard $bankCard)
    {
        Gate::authorize('view', $bankCard);

        return new BankCardResource($bankCard);
    }

    public function update(UpdateBankCardRequest $request, BankCard $bankCard)
    {
        Gate::authorize('update', $bankCard);

        try {
            DB::beginTransaction();

            $bankCard->update($request->safe()->except(['is_default']));

            if ($request->boolean('is_default')) {
                $bankCard->markAsDefault();
            }

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();

            return ApiResponse::response(message: $exception->getMessage(), status: 419);
        }

        return ApiResponse::success(
            new BankCardResource($bankCard->fresh()),
            'کارت بانکی به‌روزرسانی شد.'
        );
    }

    public function destroy(BankCard $bankCard)
    {
        Gate::authorize('delete', $bankCard);

        if ($bankCard->is_default) {
            $next = BankCard::query()
                ->where('user_id', $bankCard->user_id)
                ->where('id', '!=', $bankCard->id)
                ->where('status', BankCard::STATUS_ACTIVE)
                ->latest()
                ->first();

            $next?->markAsDefault();
        }

        $bankCard->delete();

        return ApiResponse::success(message: 'کارت بانکی حذف شد.');
    }

    public function setDefault(BankCard $bankCard)
    {
        Gate::authorize('update', $bankCard);

        $bankCard->markAsDefault();

        return ApiResponse::success(
            new BankCardResource($bankCard->fresh()),
            'کارت به عنوان پیش‌فرض تنظیم شد.'
        );
    }
}
