<?php

namespace App\Actions\Voucher;

use App\Models\User;
use App\Models\Voucher;
use App\Services\Analytics\StatsService;
use App\Services\Api\ApiFactory;
use Illuminate\Support\Facades\Log;

final class RedeemVoucherAction
{
    public function __construct(
        private ApiFactory $apiFactory,
        private StatsService $statsService,
    ) {}

    /**
     * @return array{success: bool, message: string}
     */
    public function handle(Voucher $voucher, User $user, int $characterId, ?string $ip = null): array
    {
        $api = $this->apiFactory->make($user->ID);

        if (! $this->isServerOnline()) {
            return ['success' => false, 'message' => 'Server is currently offline. Please try again later.'];
        }

        // Verify character belongs to user
        $rolesData = $api->getRoles($user->ID);
        $roles = collect($rolesData['roles'] ?? []);

        if (! $roles->firstWhere('id', $characterId)) {
            return ['success' => false, 'message' => 'Invalid character'];
        }

        try {
            $item = [
                'id' => $voucher->item_id,
                'pos' => 0,
                'count' => $voucher->count,
                'max_count' => $voucher->count,
                'data' => $voucher->octet ?? '',
                'proctype' => $voucher->proctype,
                'expire_date' => $voucher->expire_date ? strtotime($voucher->expire_date) : 0,
                'guid1' => 0,
                'guid2' => 0,
                'mask' => $voucher->mask,
            ];

            $title = 'Voucher Reward';
            $context = "You have redeemed voucher code: {$voucher->code}\nItem: {$voucher->item_name}";

            $result = $api->sendMail($characterId, $title, $context, 0, $item);

            if (! $result) {
                return ['success' => false, 'message' => 'Failed to send item. Please try again later.'];
            }

            // Update voucher
            $voucher->usage_count = $voucher->usage_count + 1;

            if ($voucher->usage_count >= $voucher->usage_limit) {
                $voucher->is_used = true;
            }

            $voucher->used_by = $user->ID;
            $voucher->used_at = now();

            if ($voucher->is_redeemed_by_ip) {
                $voucher->redeemed_ip = $ip;
            }

            $voucher->save();

            return ['success' => true, 'message' => 'Voucher redeemed successfully! Check your in-game mail.'];
        } catch (\Exception $e) {
            Log::error('Voucher redemption failed', [
                'voucher_id' => $voucher->id,
                'user_id' => $user->ID,
                'character_id' => $characterId,
                'error' => $e->getMessage(),
            ]);

            return ['success' => false, 'message' => 'An error occurred: '.$e->getMessage()];
        }
    }

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

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