<?php

namespace App\Http\Controllers\Api\V1\Admin\Wallet;

use App\Lottery\ErrorCode;
use App\Models\TransferOrder;
use App\Support\ApiMessage;
use App\Support\ApiResponse;
use App\Support\AdminScopePolicy;
use App\Support\LotteryMessage;
use App\Exceptions\WalletOperationException;
use App\Services\Wallet\LotteryTransferService;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Wallet\TransferOrderReverseRequest;
use App\Http\Requests\Admin\Wallet\TransferOrderManuallyProcessRequest;
use App\Http\Requests\Admin\Wallet\TransferOrderCompleteCreditRequest;
use Illuminate\Http\JsonResponse;

/**
 * 后台：转账订单对账操作（冲正 / 补入账 / 标记结案）。
 * PRD §12：待对账 -> 已冲正 / 已结案（manually_processed，仅改状态）。
 */
final class TransferOrderReconcileController extends Controller
{
    public function __construct(
        private readonly LotteryTransferService $transferService,
    ) {}

    public function reverse(TransferOrderReverseRequest $request, string $transferNo): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        $order = TransferOrder::query()->where('transfer_no', $transferNo)->first();
        if ($order === null) {
            return ApiMessage::errorResponse($request, 'wallet.order_not_found', ErrorCode::ClientHttpError->value, null, 404);
        }
        if (! AdminScopePolicy::transferOrderAccessible($admin, $order)) {
            return ApiMessage::errorResponse($request, 'admin.site_player_access_denied', ErrorCode::AdminForbidden->value, null, 403);
        }

        try {
            $this->transferService->reconcileTransferOrder(
                $order,
                'reverse',
                (string) $request->validated('remark', ''),
            );
        } catch (WalletOperationException $e) {
            return ApiResponse::error(
                LotteryMessage::wallet($request, $e->lotteryCode),
                $e->lotteryCode,
                null,
                $e->httpStatus,
            );
        }

        return ApiResponse::success(['transfer_no' => $transferNo, 'status' => 'reversed']);
    }

    public function manuallyProcess(TransferOrderManuallyProcessRequest $request, string $transferNo): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        $order = TransferOrder::query()->where('transfer_no', $transferNo)->first();
        if ($order === null) {
            return ApiMessage::errorResponse($request, 'wallet.order_not_found', ErrorCode::ClientHttpError->value, null, 404);
        }
        if (! AdminScopePolicy::transferOrderAccessible($admin, $order)) {
            return ApiMessage::errorResponse($request, 'admin.site_player_access_denied', ErrorCode::AdminForbidden->value, null, 403);
        }

        try {
            $this->transferService->reconcileTransferOrder(
                $order,
                'manually_process',
                (string) $request->validated('remark', ''),
            );
        } catch (WalletOperationException $e) {
            return ApiResponse::error(
                LotteryMessage::wallet($request, $e->lotteryCode),
                $e->lotteryCode,
                null,
                $e->httpStatus,
            );
        }

        return ApiResponse::success(['transfer_no' => $transferNo, 'status' => 'manually_processed']);
    }

    public function completeCredit(TransferOrderCompleteCreditRequest $request, string $transferNo): JsonResponse
    {
        $admin = $request->lotteryAdmin();
        abort_if($admin === null, 401);

        $order = TransferOrder::query()->where('transfer_no', $transferNo)->first();
        if ($order === null) {
            return ApiMessage::errorResponse($request, 'wallet.order_not_found', ErrorCode::ClientHttpError->value, null, 404);
        }
        if (! AdminScopePolicy::transferOrderAccessible($admin, $order)) {
            return ApiMessage::errorResponse($request, 'admin.site_player_access_denied', ErrorCode::AdminForbidden->value, null, 403);
        }

        try {
            $this->transferService->reconcileTransferOrder(
                $order,
                'complete_credit',
                (string) $request->validated('remark', ''),
            );
        } catch (WalletOperationException $e) {
            return ApiResponse::error(
                LotteryMessage::wallet($request, $e->lotteryCode),
                $e->lotteryCode,
                null,
                $e->httpStatus,
            );
        }

        return ApiResponse::success(['transfer_no' => $transferNo, 'status' => 'success']);
    }
}
