<?php

namespace App\Http\Controllers\Admin;

use App\Enums\TransactionSource;
use App\Enums\TransactionStatus;
use App\Enums\TransactionType;
use App\Http\Controllers\Controller;
use App\Http\Requests\AdminCreateTransactionRequest;
use App\Models\Account;
use App\Models\Transaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class AdminTransactionController extends Controller
{
    public function index(Request $request)
    {
        try {
            $query = Transaction::with('account.user');

            if ($request->filled('user_id')) {
                $query->whereHas('account', fn($q) => $q->where('user_id', $request->user_id));
            }
            if ($request->filled('account_id')) {
                $query->where('account_id', $request->account_id);
            }
            if ($request->filled('type')) {
                $query->where('type', $request->type);
            }
            if ($request->filled('status')) {
                $query->where('status', $request->status);
            }
            if ($request->filled('category')) {
                $query->where('category', $request->category);
            }
            if ($request->filled('date_from')) {
                $query->whereDate('created_at', '>=', $request->date_from);
            }
            if ($request->filled('date_to')) {
                $query->whereDate('created_at', '<=', $request->date_to);
            }

            $transactions = $query->latest()->paginate(20)->withQueryString();
            $accounts = Account::with('user')->get();

            return view('admin.transactions.index', compact('transactions', 'accounts'));
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('alert', 'An error occurred.');
        }
    }

    public function store(AdminCreateTransactionRequest $request)
    {
        try {
            $account = Account::findOrFail($request->account_id);

            $type = TransactionType::from($request->type);
            if ($type === TransactionType::Credit) {
                $account->increment('balance', $request->amount);
            } else {
                $account->decrement('balance', $request->amount);
            }

            Transaction::create([
                'account_id' => $account->id,
                'type' => $type,
                'amount' => $request->amount,
                'balance_after' => $account->fresh()->balance,
                'description' => $request->description,
                'category' => $request->category,
                'status' => TransactionStatus::Completed,
                'source' => TransactionSource::Manual,
                'reference' => 'TXN-' . strtoupper(Str::random(12)),
            ]);

            return back()->with('success', 'Transaction created successfully.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('alert', 'An error occurred.');
        }
    }

    public function edit(Transaction $transaction)
    {
        try {
            $transaction->load('account.user');

            return view('admin.transactions.edit', compact('transaction'));
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('alert', 'An error occurred.');
        }
    }

    public function update(Request $request, Transaction $transaction)
    {
        try {
            $request->validate([
                'type' => 'required|string',
                'status' => 'required|string',
                'category' => 'required|string',
                'amount' => 'required|numeric|min:0.01',
                'description' => 'required|string|max:500',
                'reference' => 'required|string|max:100',
                'balance_after' => 'required|numeric',
                'source' => 'required|string',
            ]);

            $transaction->update($request->only([
                'type', 'status', 'category', 'amount',
                'description', 'reference', 'balance_after', 'source',
            ]));

            return redirect()->route('admin.transactions')->with('success', 'Transaction updated successfully.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('alert', 'An error occurred.');
        }
    }
}
