<?php

namespace App\Http\Controllers;

use App\Models\UserWallet;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class UserWalletController extends Controller
{
    /** @phpstan-return void */
    private static function normalizeDefaultIfNeedsOne(int $userId): void
    {
        $wallets = UserWallet::where('user_id', $userId)->get();
        if ($wallets->isEmpty()) {
            return;
        }
        if ($wallets->where('is_default', true)->count() === 0) {
            $first = $wallets->sortByDesc('updated_at')->first();
            if ($first instanceof UserWallet) {
                UserWallet::whereKey($first->getKey())->update(['is_default' => true]);
            }
        }
    }

    private static function unsetOtherDefaults(int $userId, int $keepingId): void
    {
        UserWallet::query()
            ->where('user_id', $userId)
            ->whereKeyNot($keepingId)
            ->update(['is_default' => false]);
    }

    public function index(Request $request): Response
    {
        /** @var \App\Models\User $user */
        $user = $request->user();
        self::normalizeDefaultIfNeedsOne($user->id);

        return Inertia::render('balances/wallets', [
            'wallets' => $user->wallets()->get()->map(fn (UserWallet $w): array => [
                'id' => $w->id,
                'currency_network' => $w->currency_network,
                'address' => $w->address,
                'label' => $w->label,
                'is_default' => $w->is_default,
                'updated_at' => $w->updated_at?->toIso8601String(),
            ]),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();

        $validated = $request->validate([
            'currency_network' => ['required', 'string', 'max:64'],
            'address' => ['required', 'string', 'max:512'],
            'label' => ['nullable', 'string', 'max:96'],
            'is_default' => ['sometimes', 'boolean'],
        ]);

        $countBefore = $user->wallets()->count();

        $wallet = UserWallet::create([
            'user_id' => $user->id,
            'currency_network' => $validated['currency_network'],
            'address' => $validated['address'],
            'label' => $validated['label'] ?? null,
            'is_default' => $countBefore === 0 ? true : (bool) ($validated['is_default'] ?? false),
        ]);

        if ($wallet->is_default) {
            self::unsetOtherDefaults($user->id, $wallet->id);
        }

        self::normalizeDefaultIfNeedsOne($user->id);

        return redirect()->route('balances.wallets')->with('toast', __('Billetera añadida.'));
    }

    public function update(Request $request, UserWallet $userWallet): RedirectResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();
        abort_unless((int) $userWallet->user_id === $user->id, 404);

        $validated = $request->validate([
            'currency_network' => ['required', 'string', 'max:64'],
            'address' => ['required', 'string', 'max:512'],
            'label' => ['nullable', 'string', 'max:96'],
            'is_default' => ['sometimes', 'boolean'],
        ]);

        $userWallet->update([
            'currency_network' => $validated['currency_network'],
            'address' => $validated['address'],
            'label' => $validated['label'] ?? null,
            'is_default' => (bool) ($validated['is_default'] ?? $userWallet->is_default),
        ]);

        if ($userWallet->is_default) {
            self::unsetOtherDefaults($user->id, $userWallet->id);
        }

        self::normalizeDefaultIfNeedsOne($user->id);

        return redirect()->route('balances.wallets')->with('toast', __('Billetera actualizada.'));
    }

    public function destroy(Request $request, UserWallet $userWallet): RedirectResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();
        abort_unless((int) $userWallet->user_id === $user->id, 404);

        $wasDefault = $userWallet->is_default;
        $userWallet->delete();

        if ($wasDefault && $user->wallets()->exists()) {
            $nw = $user->wallets()->orderByDesc('updated_at')->first();
            if ($nw instanceof UserWallet) {
                $nw->update(['is_default' => true]);
            }
        }

        self::normalizeDefaultIfNeedsOne($user->id);

        return redirect()->route('balances.wallets')->with('toast', __('Billetera eliminada.'));
    }
}
