<?php
namespace App\Services;
use App\Enums\LedgerDirection;use App\Enums\LedgerType;use App\Models\LedgerEntry;use App\Models\Merchant;use App\Models\SettlementBatch;use App\Models\Transfer;use App\Models\User;
final class LedgerService {
 public function post(Merchant $merchant,LedgerDirection $direction,int $amountMinor,string $currency,LedgerType $type,User $actor,?Transfer $transfer=null,?SettlementBatch $batch=null,?string $note=null):LedgerEntry{
  if($amountMinor<=0)throw new \InvalidArgumentException('Ledger amount must be positive.'); if($merchant->currency_code!==$currency)throw new \LogicException('Ledger currency must match merchant currency.');
  Merchant::whereKey($merchant->id)->lockForUpdate()->firstOrFail();$last=LedgerEntry::where('merchant_id',$merchant->id)->where('currency',$currency)->orderByDesc('id')->lockForUpdate()->first();$before=$last?->balance_after_minor??0;$after=$direction===LedgerDirection::Credit?$before+$amountMinor:$before-$amountMinor;
  $entry=LedgerEntry::create(['merchant_id'=>$merchant->id,'transfer_id'=>$transfer?->id,'settlement_batch_id'=>$batch?->id,'direction'=>$direction,'amount_minor'=>$amountMinor,'currency'=>$currency,'type'=>$type,'balance_after_minor'=>$after,'note'=>$note,'created_by'=>$actor->id,'created_at'=>now()]);
  $merchant->forceFill(['float_balance_minor'=>$after])->save(); \Log::channel('financial')->info('ledger.posted',['entry_id'=>$entry->id,'merchant_id'=>$merchant->id,'direction'=>$direction->value,'amount_minor'=>$amountMinor,'currency'=>$currency,'type'=>$type->value,'transfer_id'=>$transfer?->id]); return $entry;
 }
}
