<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Account;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

class AccountController extends Controller
{
    /**
     * Listar todas as contas do usuário
     */
    public function index(Request $request): JsonResponse
    {
        $query = Account::where('user_id', Auth::id());

        // Filtros opcionais
        if ($request->has('type')) {
            $query->where('type', $request->type);
        }

        if ($request->has('is_active')) {
            $query->where('is_active', $request->boolean('is_active'));
        }

        $accounts = $query->orderBy('name')->get();

        return response()->json([
            'success' => true,
            'data' => $accounts,
            'types' => Account::TYPES,
        ]);
    }

    /**
     * Criar nova conta
     */
    public function store(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'type' => ['required', Rule::in(array_keys(Account::TYPES))],
            'bank_name' => 'nullable|string|max:100',
            'account_number' => 'nullable|string|max:50',
            'initial_balance' => 'nullable|numeric',
            'credit_limit' => 'nullable|numeric',
            'currency' => 'nullable|string|size:3',
            'color' => 'nullable|string|max:7',
            'icon' => 'nullable|string|max:50',
            'description' => 'nullable|string',
            'is_active' => 'nullable|boolean',
            'include_in_total' => 'nullable|boolean',
        ]);

        $validated['user_id'] = Auth::id();
        $validated['current_balance'] = $validated['initial_balance'] ?? 0;

        $account = Account::create($validated);

        return response()->json([
            'success' => true,
            'message' => 'Conta criada com sucesso',
            'data' => $account,
        ], 201);
    }

    /**
     * Exibir uma conta específica
     */
    public function show(int $id): JsonResponse
    {
        $account = Account::where('user_id', Auth::id())->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $account,
        ]);
    }

    /**
     * Atualizar uma conta
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $account = Account::where('user_id', Auth::id())->findOrFail($id);

        $validated = $request->validate([
            'name' => 'sometimes|required|string|max:100',
            'type' => ['sometimes', 'required', Rule::in(array_keys(Account::TYPES))],
            'bank_name' => 'nullable|string|max:100',
            'account_number' => 'nullable|string|max:50',
            'initial_balance' => 'nullable|numeric',
            'credit_limit' => 'nullable|numeric',
            'currency' => 'nullable|string|size:3',
            'color' => 'nullable|string|max:7',
            'icon' => 'nullable|string|max:50',
            'description' => 'nullable|string',
            'is_active' => 'nullable|boolean',
            'include_in_total' => 'nullable|boolean',
        ]);

        $account->update($validated);

        return response()->json([
            'success' => true,
            'message' => 'Conta atualizada com sucesso',
            'data' => $account->fresh(),
        ]);
    }

    /**
     * Deletar uma conta (soft delete)
     */
    public function destroy(int $id): JsonResponse
    {
        $account = Account::where('user_id', Auth::id())->findOrFail($id);
        $account->delete();

        return response()->json([
            'success' => true,
            'message' => 'Conta excluída com sucesso',
        ]);
    }

    /**
     * Retorna o saldo total de todas as contas
     */
    public function totalBalance(): JsonResponse
    {
        $accounts = Account::where('user_id', Auth::id())
            ->active()
            ->includeInTotal()
            ->get();

        $total = 0;
        foreach ($accounts as $account) {
            // Para passivos e cartões de crédito, o saldo é negativo
            if ($account->isCreditAccount()) {
                $total += (float) $account->current_balance; // já é negativo
            } else {
                $total += (float) $account->current_balance;
            }
        }

        return response()->json([
            'success' => true,
            'data' => [
                'total_balance' => $total,
                'accounts_count' => $accounts->count(),
            ],
        ]);
    }

    /**
     * Recalcular saldos de todas as contas do usuário
     */
    public function recalculateBalances(): JsonResponse
    {
        $accounts = Account::where('user_id', Auth::id())->get();
        
        $results = [];
        foreach ($accounts as $account) {
            $oldBalance = (float) $account->current_balance;
            $newBalance = $account->recalculateBalance();
            
            $results[] = [
                'id' => $account->id,
                'name' => $account->name,
                'old_balance' => $oldBalance,
                'new_balance' => $newBalance,
                'difference' => $newBalance - $oldBalance,
            ];
        }

        return response()->json([
            'success' => true,
            'message' => 'Saldos recalculados com sucesso',
            'data' => $results,
        ]);
    }

    /**
     * Recalcular saldo de uma conta específica
     */
    public function recalculateBalance(int $id): JsonResponse
    {
        $account = Account::where('user_id', Auth::id())->findOrFail($id);
        
        $oldBalance = (float) $account->current_balance;
        $newBalance = $account->recalculateBalance();

        return response()->json([
            'success' => true,
            'message' => 'Saldo recalculado com sucesso',
            'data' => [
                'id' => $account->id,
                'name' => $account->name,
                'old_balance' => $oldBalance,
                'new_balance' => $newBalance,
                'difference' => $newBalance - $oldBalance,
            ],
        ]);
    }

    /**
     * Ajustar saldo de uma conta definindo o saldo real atual
     * Calcula e atualiza o initial_balance para que: initial_balance + créditos - débitos = saldo_desejado
     */
    public function adjustBalance(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'target_balance' => 'required|numeric',
        ]);

        $account = Account::where('user_id', Auth::id())->findOrFail($id);
        
        $targetBalance = (float) $validated['target_balance'];
        $oldInitialBalance = (float) $account->initial_balance;
        $oldCurrentBalance = (float) $account->current_balance;
        
        // Calcular soma de transações
        $credits = (float) $account->transactions()
            ->where('type', 'credit')
            ->where('status', 'completed')
            ->sum('amount');
        
        $debits = (float) $account->transactions()
            ->where('type', 'debit')
            ->where('status', 'completed')
            ->sum('amount');
        
        // Calcular novo initial_balance: target = initial + credits - debits
        // initial = target - credits + debits
        $newInitialBalance = $targetBalance - $credits + $debits;
        
        // Atualizar conta
        $account->update([
            'initial_balance' => $newInitialBalance,
            'current_balance' => $targetBalance,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Saldo ajustado com sucesso',
            'data' => [
                'id' => $account->id,
                'name' => $account->name,
                'old_initial_balance' => $oldInitialBalance,
                'new_initial_balance' => $newInitialBalance,
                'old_current_balance' => $oldCurrentBalance,
                'new_current_balance' => $targetBalance,
                'credits_sum' => $credits,
                'debits_sum' => $debits,
            ],
        ]);
    }
}
