<?php

namespace App\Http\Controllers\Frontend\Voucher;

use App\Actions\Voucher\RedeemVoucherAction;
use App\Actions\Voucher\ValidateVoucherAction;
use App\Http\Controllers\Controller;
use App\Http\Requests\Frontend\Voucher\CheckVoucherRequest;
use App\Http\Requests\Frontend\Voucher\RedeemVoucherRequest;
use App\Http\Resources\BaseResource;
use App\Models\Voucher;
use App\Services\Analytics\StatsService;
use App\Services\Api\ApiFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Inertia\Response;

final class VoucherController extends Controller
{
    public function __construct(
        private ApiFactory $apiFactory,
        private StatsService $statsService,
        private ValidateVoucherAction $validateVoucher,
        private RedeemVoucherAction $redeemVoucher,
    ) {}

    /**
     * Display voucher redeem page.
     */
    public function index(): Response
    {
        $user = Auth::user();
        $api = $this->apiFactory->make($user->ID);

        $serverOnline = $this->isServerOnline();
        $characters = [];

        if ($serverOnline) {
            $rolesData = $api->getRoles($user->ID);
            $roles = $rolesData['roles'] ?? [];

            foreach ($roles as $role) {
                $roleBase = $api->getRoleBase($role['id']);

                $characters[] = [
                    'id' => $role['id'],
                    'name' => $role['name'],
                    'cls' => ($roleBase ?? [])['cls'] ?? 0,
                    'level' => $role['level'] ?? 0,
                ];
            }
        }

        return Inertia::render('frontend/voucher/index', [
            'characters' => $characters,
            'serverOnline' => $serverOnline,
        ]);
    }

    /**
     * Check if voucher code is valid.
     */
    public function checkVoucher(CheckVoucherRequest $request): JsonResponse
    {
        $user = Auth::user();

        if (! $this->isServerOnline()) {
            return BaseResource::makeEnvelope(
                resource: null,
                success: false,
                error: 'Server is currently offline. Please try again later.',
                status: 400,
            );
        }

        $result = $this->validateVoucher->handle(
            code: $request->getCode(),
            user: $user,
            ip: $request->ip(),
        );

        if (! $result['valid']) {
            $code = $request->getCode();
            $normalizedCode = Voucher::normalizeCode($code);

            \Log::info('Voucher check validation failed', [
                'input_length' => strlen($code),
                'input_prefix' => substr($code, 0, 4),
                'input_suffix' => substr($code, -4),
                'normalized_length' => strlen($normalizedCode),
                'normalized_prefix' => substr($normalizedCode, 0, 4),
                'normalized_suffix' => substr($normalizedCode, -4),
                'message' => $result['message'],
                'voucher_exists' => Voucher::byCode($code)->exists(),
                'user_id' => $user->ID,
            ]);
        }

        return BaseResource::makeEnvelope(
            resource: ['message' => $result['message']],
            success: $result['valid'],
            error: $result['valid'] ? null : $result['message'],
            status: $result['valid'] ? 200 : 400,
        );
    }

    /**
     * Redeem a voucher.
     */
    public function redeem(RedeemVoucherRequest $request)
    {
        $user = Auth::user();

        \Log::info('Voucher redeem request', [
            'code' => $request->input('code'),
            'getCode' => $request->getCode(),
            'character_id' => $request->input('character_id'),
            'getCharacterId' => $request->getCharacterId(),
            'user_id' => $user->ID,
            'ip' => $request->ip(),
            'server_online' => $this->isServerOnline(),
        ]);

        if (! $this->isServerOnline()) {
            return back()->withErrors(['code' => 'Server is currently offline. Please try again later.']);
        }

        $validation = $this->validateVoucher->handle(
            code: $request->getCode(),
            user: $user,
            ip: $request->ip(),
        );

        \Log::info('Voucher redeem validation', [
            'valid' => $validation['valid'],
            'message' => $validation['message'],
            'voucher_id' => $validation['voucher']?->id,
        ]);

        if (! $validation['valid']) {
            return back()->withErrors(['code' => $validation['message']]);
        }

        $result = $this->redeemVoucher->handle(
            voucher: $validation['voucher'],
            user: $user,
            characterId: $request->getCharacterId(),
            ip: $request->ip(),
        );

        \Log::info('Voucher redeem result', [
            'success' => $result['success'],
            'message' => $result['message'],
        ]);

        if ($result['success']) {
            return to_route('dashboard.voucher.index')
                ->with('success', $result['message']);
        }

        return back()->withErrors(['code' => $result['message']]);
    }

    private function isServerOnline(): bool
    {
        $onlineData = $this->statsService->getOnlineData();

        return (bool) ($onlineData['serverOnline'] ?? false);
    }
}
