<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\ManagedEnvironment;
use App\Models\ReviewPack;
use App\Models\User;
use App\Services\Audit\WorkspaceAuditLogger;
use App\Support\Audit\AuditActionId;
use App\Support\Auth\Capabilities;
use App\Support\ReviewPackStatus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ReviewPackDownloadController extends Controller
{
    public function __invoke(Request $request, ReviewPack $reviewPack): StreamedResponse
    {
        $user = $request->user();
        $tenant = $reviewPack->tenant;

        if (! $user instanceof User || ! $tenant instanceof ManagedEnvironment) {
            throw new NotFoundHttpException;
        }

        if (! $user->canAccessTenant($tenant)) {
            throw new NotFoundHttpException;
        }

        if (! $user->can(Capabilities::REVIEW_PACK_VIEW, $tenant)) {
            abort(403);
        }

        if ($reviewPack->status !== ReviewPackStatus::Ready->value) {
            throw new NotFoundHttpException;
        }

        if ($reviewPack->expires_at && $reviewPack->expires_at->isPast()) {
            throw new NotFoundHttpException;
        }

        $disk = Storage::disk($reviewPack->file_disk ?? 'exports');

        if (! $disk->exists($reviewPack->file_path)) {
            throw new NotFoundHttpException;
        }

        app(WorkspaceAuditLogger::class)->log(
            workspace: $tenant->workspace,
            action: AuditActionId::ReviewPackDownloaded,
            context: [
                'metadata' => [
                    'review_pack_id' => (int) $reviewPack->getKey(),
                    'environment_review_id' => $reviewPack->environment_review_id !== null
                        ? (int) $reviewPack->environment_review_id
                        : null,
                    'source_surface' => (string) $request->query('source_surface', 'review_pack'),
                    'review_id' => $request->query('review_id'),
                    'tenant_filter_id' => $request->query('tenant_filter_id'),
                    'interpretation_version' => $request->query('interpretation_version'),
                ],
            ],
            actor: $user,
            resourceType: 'review_pack',
            resourceId: (string) $reviewPack->getKey(),
            targetLabel: sprintf('Review pack #%d', (int) $reviewPack->getKey()),
            tenant: $tenant,
            operationRunId: $reviewPack->operation_run_id,
        );

        $filename = sprintf(
            'review-pack-%s-%s.zip',
            $tenant?->external_id ?? 'unknown',
            $reviewPack->generated_at?->format('Y-m-d') ?? now()->format('Y-m-d'),
        );

        return $disk->download($reviewPack->file_path, $filename, [
            'X-Review-Pack-SHA256' => $reviewPack->sha256 ?? '',
        ]);
    }
}
