<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Services\WalletService;
use Illuminate\Http\Request;
use OpenApi\Attributes as OA;

class WalletController extends Controller
{
    public function __construct(private WalletService $walletService) {}

    #[OA\Get(
        path: '/api/wallet/balance',
        operationId: 'walletBalance',
        summary: 'Get wallet balance',
        description: 'Returns the current balance, loyalty points, and pending withdrawals for the authenticated user\'s wallet.',
        security: [['passport' => []]],
        tags: ['Wallet'],
        responses: [
            new OA\Response(response: 200, description: 'Wallet data',
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: 'data', ref: '#/components/schemas/WalletResource'),
                ])),
            new OA\Response(response: 401, description: 'Unauthenticated',
                content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedError')),
        ]
    )]
    public function balance(Request $request)
    {
        $wallet = $this->walletService->getOrCreateWallet($request->user());
        return response()->json(['data' => $wallet]);
    }

    #[OA\Get(
        path: '/api/wallet/transactions',
        operationId: 'walletTransactions',
        summary: 'List wallet transactions',
        description: 'Returns paginated transaction history ordered by most recent.',
        security: [['passport' => []]],
        tags: ['Wallet'],
        parameters: [
            new OA\Parameter(name: 'page', in: 'query', required: false,
                schema: new OA\Schema(type: 'integer', default: 1)),
        ],
        responses: [
            new OA\Response(response: 200, description: 'Paginated transactions',
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: 'data', type: 'object',
                        properties: [
                            new OA\Property(property: 'data', type: 'array',
                                items: new OA\Items(ref: '#/components/schemas/WalletTransactionResource')),
                            new OA\Property(property: 'meta', ref: '#/components/schemas/PaginationMeta'),
                        ]),
                ])),
            new OA\Response(response: 401, description: 'Unauthenticated',
                content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedError')),
        ]
    )]
    public function transactions(Request $request)
    {
        $wallet = $this->walletService->getOrCreateWallet($request->user());
        $transactions = $wallet->transactions()->paginate(20);
        return response()->json(['data' => $transactions]);
    }

    public function withdraw(Request $request)
    {
        $request->validate([
            'amount'         => 'required|numeric|min:100',
            'bank_name'      => 'required|string',
            'account_number' => 'required|string',
            'account_name'   => 'required|string',
        ]);

        if (!$request->user()->vendor) {
            return response()->json(['message' => 'Only vendors can withdraw from their wallet.'], 403);
        }

        $wallet = $this->walletService->getOrCreateWallet($request->user());

        if ($wallet->balance < $request->amount) {
            return response()->json(['message' => 'Insufficient balance.'], 422);
        }

        $wallet->decrement('balance', $request->amount);
        $wallet->increment('pending_withdrawal', $request->amount);

        $txn = $wallet->transactions()->create([
            'type'              => 'withdrawal',
            'amount'            => $request->amount,
            'balance_before'    => $wallet->balance + $request->amount,
            'balance_after'     => $wallet->balance,
            'reference'         => 'WDR-' . strtoupper(uniqid()),
            'description'       => 'Withdrawal request',
            'status'            => 'pending',
            'transactable_id'   => 0,
            'transactable_type' => 'withdrawal',
            'meta'              => $request->only('bank_name', 'account_number', 'account_name'),
        ]);

        return response()->json(['message' => 'Withdrawal request submitted.', 'data' => $txn], 201);
    }
}
