<?php

namespace App\Services;

use App\Models\FinancialTransaction;
use App\Models\FinancialTreasury;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Exception;

class FinancialTransactionService
{
    /**
     * Record an Income transaction (Deposit).
     */
    public function recordIncome(
        float $amount,
        int $treasuryId,
        int $categoryId,
        string $description,
        ?Model $relatedModel = null,
        ?int $projectId = null,
        ?string $date = null
    ): FinancialTransaction {
        return $this->recordTransaction(
            'in',
            $amount,
            $treasuryId,
            $categoryId,
            $description,
            $relatedModel,
            $projectId,
            $date
        );
    }

    /**
     * Record an Expense transaction (Withdrawal).
     */
    public function recordExpense(
        float $amount,
        int $treasuryId,
        int $categoryId,
        string $description,
        ?Model $relatedModel = null,
        ?int $projectId = null,
        ?string $date = null
    ): FinancialTransaction {
        return $this->recordTransaction(
            'out',
            $amount,
            $treasuryId,
            $categoryId,
            $description,
            $relatedModel,
            $projectId,
            $date
        );
    }

    /**
     * Core method to record transaction and update balance.
     */
    protected function recordTransaction(
        string $type,
        float $amount,
        int $treasuryId,
        int $categoryId,
        string $description,
        ?Model $relatedModel,
        ?int $projectId,
        ?string $date
    ): FinancialTransaction {
        return DB::transaction(function () use ($type, $amount, $treasuryId, $categoryId, $description, $relatedModel, $projectId, $date) {

            $treasury = FinancialTreasury::findOrFail($treasuryId);

            // Get currency info from Treasury
            $currency_id = $treasury->currency_id;
            // Get rate from Currency Model (or better, snapshot it?)
            // If the treasury has a currency_id, we fetch its current rate.
            $rate = 1.0;
            if ($currency_id) {
                // Assuming we have relationship or just fetch
                $currency = \App\Models\Currency::find($currency_id);
                $rate = $currency ? $currency->exchange_rate : 1.0;
            }

            // Create Transaction Record
            $transaction = FinancialTransaction::create([
                'treasury_id' => $treasuryId,
                'category_id' => $categoryId,
                'project_id' => $projectId,
                'user_id' => auth()->id() ?? 1, // Fallback for system automations
                'amount' => $amount,
                'currency_id' => $currency_id,
                'exchange_rate' => $rate,
                'type' => $type,
                'date' => $date ?? now()->toDateString(),
                'description' => $description,
                'model_type' => $relatedModel ? get_class($relatedModel) : null,
                'model_id' => $relatedModel ? $relatedModel->id : null,
            ]);

            // Update Treasury Balance
            if ($type === 'in') {
                $treasury->increment('balance', $amount);
            } else {
                $treasury->decrement('balance', $amount);
            }

            return $transaction;
        });
    }
}
