<?php

namespace App\Http\Controllers;

use App\Models\FinancialAccount;
use App\Models\Scopes\BranchScope;
use App\Services\AuditService;
use App\Services\BranchAccessService;
use App\Services\FinancialAccountingService;
use Carbon\CarbonImmutable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class FinancialTransferController extends Controller
{
    public function __construct(private BranchAccessService $branchAccess)
    {
    }

    public function create(Request $request): View
    {
        return view('accounting.transfers.create',['accounts'=>$this->accounts($request)]);
    }

    public function store(Request $request, FinancialAccountingService $service): RedirectResponse
    {
        $data=$request->validate([
            'source_account_id'=>['required','integer','exists:financial_accounts,id'],
            'destination_account_id'=>['required','integer','different:source_account_id','exists:financial_accounts,id'],
            'amount'=>['required','decimal:0,2','min:0.01'],
            'date'=>['required','date'],
            'reference'=>['nullable','string','max:150'],
            'notes'=>['nullable','string','max:2000'],
        ]);
        $source=FinancialAccount::withoutGlobalScope(BranchScope::class)->findOrFail($data['source_account_id']);
        $destination=FinancialAccount::withoutGlobalScope(BranchScope::class)->findOrFail($data['destination_account_id']);
        $this->branchAccess->assertBranchAccessible($request->user(), $source->branch_id);
        $this->branchAccess->assertBranchAccessible($request->user(), $destination->branch_id);

        $transfer=$service->transfer($source,$destination,(string)$data['amount'],CarbonImmutable::parse($data['date']),$data['reference'] ?? null,$data['notes'] ?? null,$request->user());
        AuditService::record('financial_transfer.posted',$transfer,[],['amount'=>$transfer->amount,'source_account_id'=>$source->id,'destination_account_id'=>$destination->id],$source->branch_id);
        return redirect()->route('accounts.show',$source)->with('success','Account transfer posted successfully.');
    }

    private function accounts(Request $request)
    {
        $branchIds=$this->branchAccess->accessibleBranchIds($request->user());
        return FinancialAccount::with('branch')->whereIn('branch_id',$branchIds)->where('status','active')->orderBy('name')->get();
    }
}
