<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\InvestmentTransaction;
use App\Models\User;
use App\Support\AdminDebugAudit;
use App\Support\InvestmentLedger;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;

class AdminDebugController extends Controller
{
    public function index(): Response
    {
        abort_unless(config('app.allow_adjustments'), 404);

        return Inertia::render('admin/debug-audit', [
            // Compatibilidad con bundles anteriores; la UI actual carga secciones vía JSON.
            'summary' => [
                'investment_balance_issues' => 0,
                'user_withdrawable_issues' => 0,
                'manual_balance_credits' => 0,
                'manual_balance_revertable' => 0,
                'accrual_inconsistencies' => 0,
            ],
            'balance_inconsistencies' => [
                'investments' => [],
                'users' => [],
            ],
            'manual_balance_credits' => [],
            'accrual_inconsistencies' => [
                'items' => [],
                'scanned' => 0,
                'truncated' => false,
                'total_period_accruals' => 0,
            ],
        ]);
    }

    public function sectionInvestments(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $page = max(1, (int) $request->integer('page', 1));

        return response()->json(
            AdminDebugAudit::paginateArray(
                AdminDebugAudit::investmentBalanceInconsistencies(),
                $page,
                AdminDebugAudit::PER_PAGE,
                'admin.debug.sections.investments',
            ),
        );
    }

    public function sectionUsers(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $page = max(1, (int) $request->integer('page', 1));

        return response()->json(
            AdminDebugAudit::paginateArray(
                AdminDebugAudit::userWithdrawableInconsistencies(),
                $page,
                AdminDebugAudit::PER_PAGE,
                'admin.debug.sections.users',
            ),
        );
    }

    public function sectionManualCredits(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $page = max(1, (int) $request->integer('page', 1));

        return response()->json(
            AdminDebugAudit::paginatedManualBalanceCredits($page),
        );
    }

    public function sectionAccruals(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $page = max(1, (int) $request->integer('page', 1));

        return response()->json(
            AdminDebugAudit::paginatedPeriodAccrualInconsistencies($page),
        );
    }

    public function sectionBalanceConsolidation(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $page = max(1, (int) $request->integer('page', 1));

        return response()->json(
            AdminDebugAudit::paginatedBalanceConsolidationCandidates($page),
        );
    }

    public function bulkConsolidateBalancePreview(Request $request): JsonResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $validated = $request->validate([
            'user_ids' => ['required', 'array', 'min:1'],
            'user_ids.*' => ['integer', 'exists:users,id'],
        ]);

        $preview = AdminDebugAudit::bulkBalanceConsolidationPreview($validated['user_ids']);

        return response()->json([
            'user_count' => $preview['user_count'],
            'action_count' => $preview['action_count'],
            'total_amount_to_move_usd' => number_format($preview['total_amount_to_move_usd'], 2, '.', ''),
            'users' => $preview['users'],
        ]);
    }

    public function bulkConsolidateBalance(Request $request): RedirectResponse
    {
        abort_unless(config('app.allow_adjustments'), 404);

        $validated = $request->validate([
            'user_ids' => ['required', 'array', 'min:1'],
            'user_ids.*' => ['integer', 'exists:users,id'],
        ]);

        $result = AdminDebugAudit::executeBulkBalanceConsolidation($validated['user_ids']);

        if ($result['processed'] === 0) {
            Inertia::flash('toast', [
                'type' => 'info',
                'message' => 'No había saldo retirable disperso que consolidar para los usuarios seleccionados.',
            ]);

            return redirect()->route('admin.debug.index');
        }

        Inertia::flash('toast', [
            'type' => 'success',
            'message' => sprintf(
                'Consolidación completada: %d usuario(s), US$ %s movidos al balance general.%s',
                $result['processed'],
                number_format($result['total_moved_usd'], 2, '.', ','),
                $result['skipped'] > 0
                    ? sprintf(' %d omitido(s) sin cambios pendientes.', $result['skipped'])
                    : '',
            ),
        ]);

        return redirect()->route('admin.debug.index');
    }

    /**
     * Revierte acreditación manual desde la consola de auditoría (misma lógica que usuarios).
     */
    public function revertManualBalance(
        Request $request,
        User $user,
        InvestmentTransaction $transaction,
    ): RedirectResponse {
        abort_unless(config('app.allow_adjustments'), 404);

        abort_unless(
            $transaction->investment?->user_id === $user->id,
            404,
        );

        /** @var User $admin */
        $admin = $request->user();

        try {
            InvestmentLedger::revertAdminBalanceCredit($transaction, $admin);
        } catch (ValidationException $exception) {
            Inertia::flash('toast', [
                'type' => 'error',
                'message' => collect($exception->errors())->flatten()->first()
                    ?? 'No se pudo revertir la acreditación.',
            ]);

            return redirect()->route('admin.debug.index');
        }

        Inertia::flash('toast', [
            'type' => 'success',
            'message' => sprintf(
                'Se revirtió la acreditación manual de US$ %s para %s.',
                number_format((float) $transaction->amount, 2, '.', ''),
                trim("{$user->first_name} {$user->last_name}"),
            ),
        ]);

        return redirect()->route('admin.debug.index');
    }
}
