<?php

namespace App\Http\Controllers;

use App\Domain\Financial\Models\Expense;
use App\Domain\Shared\Context\BranchContext;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;

/**
 * Receipts live on the private disk, so they can only be read back through
 * here — never by guessing a URL under /storage.
 */
class ExpenseAttachmentController extends Controller
{
    public function show(Expense $expense): StreamedResponse
    {
        return $this->stream($expense, 'inline');
    }

    public function download(Expense $expense): StreamedResponse
    {
        return $this->stream($expense, 'attachment');
    }

    private function stream(Expense $expense, string $disposition): StreamedResponse
    {
        Gate::authorize('expenses.create');
        $this->ensureVisible($expense);

        abort_unless($expense->hasAttachment(), 404);

        $disk = Storage::disk($expense->attachmentDiskName());

        abort_unless($disk->exists($expense->attachment_path), 404);

        $filename = $expense->attachment_name ?: basename($expense->attachment_path);

        return $disk->download($expense->attachment_path, $filename, [
            'Content-Type' => $expense->attachment_mime ?: 'application/octet-stream',
            'Content-Disposition' => $disposition . '; filename="' . addslashes($filename) . '"',
        ]);
    }

    /**
     * The academy scope is already global; the branch is not. Someone looking
     * at one branch has no business reading another branch's receipts.
     */
    private function ensureVisible(Expense $expense): void
    {
        // SuperAdmin requests never bind an academy; skip rather than throw a
        // BindingResolutionException at them.
        if (app()->has('current_academy')) {
            abort_unless($expense->academy_id === app('current_academy')->id, 403);
        }

        $branchId = app(BranchContext::class)->branchId();

        abort_if($branchId && $expense->branch_id && $expense->branch_id !== $branchId, 403);
    }
}
