<?php

namespace App\Http\Controllers\School;

use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class FilesController extends Controller
{
    private const MAX_FILE_BYTES = 10 * 1024 * 1024; // 10 MB
    private const ALLOWED_MIMES = [
        'application/pdf', 'image/jpeg', 'image/png', 'image/gif',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'text/plain', 'text/csv',
    ];

    public function index(Request $request): InertiaResponse
    {
        $schoolId = $this->currentSchoolId($request);

        $files = DB::table('files')
            ->leftJoin('users', 'users.id', '=', 'files.uploaded_by')
            ->where('files.school_id', $schoolId)
            ->orderByDesc('files.created_at')
            ->limit(200)
            ->get([
                'files.id',
                'files.original_name',
                'files.mime_type',
                'files.size_bytes',
                'files.visibility',
                'files.created_at',
                'users.first_name',
                'users.last_name',
            ]);

        return Inertia::render('School/Files', [
            'files' => $files->map(fn ($f): array => [
                'id' => (int) $f->id,
                'name' => $f->original_name ?? 'بدون نام',
                'mime' => $f->mime_type ?? '—',
                'size' => $this->humanSize((int) ($f->size_bytes ?? 0)),
                'visibility' => $f->visibility === 'public' ? 'عمومی' : 'خصوصی',
                'uploadedBy' => trim(($f->first_name ?? '').' '.($f->last_name ?? '')) ?: '—',
                'createdAt' => $this->jalaliDate($f->created_at, true),
            ])->values(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $schoolId = $this->currentSchoolId($request);

        $request->validate([
            'file' => ['required', 'file', 'max:10240'],
            'visibility' => ['nullable', 'in:private,public'],
        ]);

        $uploaded = $request->file('file');
        abort_unless($uploaded && $uploaded->isValid(), 422);

        $mime = $uploaded->getMimeType() ?? '';
        if (! in_array($mime, self::ALLOWED_MIMES, true)) {
            return back()->withErrors(['file' => 'نوع فایل مجاز نیست.']);
        }

        if ($uploaded->getSize() > self::MAX_FILE_BYTES) {
            return back()->withErrors(['file' => 'حداکثر حجم فایل ۱۰ مگابایت است.']);
        }

        $path = $uploaded->store("schools/{$schoolId}/files", 'local');

        DB::table('files')->insert([
            'school_id' => $schoolId,
            'uploaded_by' => $request->user()?->id,
            'disk' => 'local',
            'path' => $path,
            'original_name' => $uploaded->getClientOriginalName(),
            'mime_type' => $mime,
            'size_bytes' => $uploaded->getSize(),
            'visibility' => $request->input('visibility', 'private'),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return redirect()->route('school.files')->with('success', 'فایل آپلود شد.');
    }

    public function download(Request $request, int $id): Response|\Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        $schoolId = $this->currentSchoolId($request);

        $file = DB::table('files')
            ->where('id', $id)
            ->where('school_id', $schoolId)
            ->first();

        abort_unless($file, 404);

        if (! Storage::disk('local')->exists($file->path)) {
            abort(404, 'فایل یافت نشد.');
        }

        return Storage::disk('local')->download($file->path, $file->original_name);
    }

    public function destroy(Request $request, int $id): RedirectResponse
    {
        $schoolId = $this->currentSchoolId($request);

        $file = DB::table('files')
            ->where('id', $id)
            ->where('school_id', $schoolId)
            ->first();

        abort_unless($file, 404);

        Storage::disk('local')->delete($file->path);
        DB::table('files')->where('id', $id)->delete();

        return redirect()->route('school.files')->with('success', 'فایل حذف شد.');
    }

    private function humanSize(int $bytes): string
    {
        if ($bytes < 1024) {
            return $bytes.' B';
        }
        if ($bytes < 1048576) {
            return round($bytes / 1024, 1).' KB';
        }

        return round($bytes / 1048576, 1).' MB';
    }
}
