<?php

namespace App\Http\Controllers\Meet;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Meet\Concerns\ScopesToAccount;
use App\Models\Recording;
use App\Services\Meet\RecordingService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\StreamedResponse;

class RecordingController extends Controller
{
    use ScopesToAccount;

    public function __construct(
        protected RecordingService $recordings,
    ) {}

    public function index(Request $request): View
    {
        $this->authorizeAbility($request, 'meetings.view');
        $owner = $this->ownerRef($request);
        $organization = $this->organization($request);

        $recordings = Recording::owned($owner)
            ->whereHas('session.room', fn ($q) => $q->where('organization_id', $organization->id))
            ->with(['session.room'])
            ->orderByDesc('created_at')
            ->paginate(20);

        return view('meet.recordings.index', compact('recordings'));
    }

    public function show(Request $request, Recording $recording): View
    {
        $this->authorizeAbility($request, 'meetings.view');
        $this->authorizeOwner($request, $recording);
        $recording->load(['session.room', 'session.aiSummaries', 'session.participants']);
        $recording = $this->recordings->resolveProcessingState($recording);

        $canManage = app(\App\Services\Meet\MeetPermissions::class)
            ->can($this->member($request), 'meetings.manage');

        return view('meet.recordings.show', compact('recording', 'canManage'));
    }

    public function download(Request $request, Recording $recording): StreamedResponse
    {
        $this->authorizeAbility($request, 'meetings.view');
        $this->authorizeOwner($request, $recording);
        $recording = $this->recordings->resolveProcessingState($recording);
        abort_unless($recording->hasPlayableFile(), 404, 'Recording file is not available.');
        abort_unless(app(\App\Services\Meet\MeetBillingService::class)->storageIsAccessible($recording), 402, 'Recording storage billing is overdue. Top up your Ladill wallet to download this recording.');

        $disk = Storage::disk(config('meet.recordings.disk', 'local'));
        $extension = strtolower(pathinfo($recording->storage_path, PATHINFO_EXTENSION) ?: 'webm');
        $mime = match ($extension) {
            'webm' => 'video/webm',
            'mp4' => 'video/mp4',
            'mkv' => 'video/x-matroska',
            default => 'application/octet-stream',
        };
        $filename = \Illuminate\Support\Str::slug($recording->session->room->title).'.'.$extension;

        return response()->streamDownload(function () use ($disk, $recording) {
            echo $disk->get($recording->storage_path);
        }, $filename, ['Content-Type' => $mime]);
    }

    public function destroy(Request $request, Recording $recording): RedirectResponse
    {
        $this->authorizeAbility($request, 'meetings.manage');
        $this->authorizeOwner($request, $recording);

        $this->recordings->delete($recording, $this->ownerRef($request));

        return redirect()->route('meet.recordings.index')->with('success', 'Recording deleted.');
    }
}
