<?php

namespace App\Http\Controllers\Guru;

use App\Http\Controllers\Controller;
use App\Models\Materi;
use App\Models\Kelas;
use App\Models\MataPelajaran;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;

class MateriController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): View
    {
        $guruId = auth()->id();

        // Calculate dynamic card statistics
        $totalMateri = Materi::where('guru_id', $guruId)->count();
        $materiAktif = Materi::where('guru_id', $guruId)->where('status', 'aktif')->count();
        $materiDraft = Materi::where('guru_id', $guruId)->where('status', 'draft')->count();
        $totalUpload = Materi::where('guru_id', $guruId)->count();

        // Build filtered query
        $query = Materi::where('guru_id', $guruId)->with(['kelas', 'mataPelajaran']);

        // Search query
        if ($request->has('search') && $request->search != '') {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('judul', 'like', "%{$search}%")
                  ->orWhereHas('mataPelajaran', function ($qm) use ($search) {
                      $qm->where('nama_mapel', 'like', "%{$search}%");
                  })
                  ->orWhereHas('kelas', function ($qk) use ($search) {
                      $qk->where('nama_kelas', 'like', "%{$search}%");
                  });
            });
        }

        // Dropdown Filters
        if ($request->has('filter_mapel') && $request->filter_mapel != '') {
            $query->where('mata_pelajaran_id', $request->filter_mapel);
        }
        if ($request->has('filter_kelas') && $request->filter_kelas != '') {
            $query->where('kelas_id', $request->filter_kelas);
        }
        if ($request->has('filter_status') && $request->filter_status != '') {
            $query->where('status', $request->filter_status);
        }

        $materiList = $query->latest()->paginate(10)->withQueryString();

        $kelas = Kelas::orderBy('nama_kelas')->get();
        $mataPelajaran = MataPelajaran::orderBy('nama_mapel')->get();

        return view('guru.materi', [
            'materiList' => $materiList,
            'kelas' => $kelas,
            'mataPelajaran' => $mataPelajaran,
            'totalMateri' => $totalMateri,
            'materiAktif' => $materiAktif,
            'materiDraft' => $materiDraft,
            'totalUpload' => $totalUpload,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): RedirectResponse
    {
        if ($request->has('kelas_id') && !$request->has('kelas_ids')) {
            $request->merge(['kelas_ids' => [$request->kelas_id]]);
        }

        if ($request->has('kelas_ids')) {
            $kelasIds = array_values(array_filter(array_unique($request->kelas_ids)));
            $request->merge(['kelas_ids' => $kelasIds]);
        }

        $request->validate([
            'judul' => 'required|string|max:255',
            'mata_pelajaran_id' => 'required|exists:mata_pelajaran,id',
            'kelas_ids' => 'required|array',
            'kelas_ids.*' => 'required|exists:kelas,id|distinct',
            'status' => 'required|in:aktif,draft',
            'deskripsi' => 'nullable|string',
            'file' => 'required|file',
            'redirect_kelas_id' => 'nullable|exists:kelas,id',
            'redirect_mapel_id' => 'nullable|exists:mata_pelajaran,id',
        ]);

        $file = $request->file('file');
        $extension = strtolower($file->getClientOriginalExtension());
        $size = $file->getSize(); // Size in bytes
        $sizeKb = $size / 1024;

        // Custom validation limits based on extension
        $maxSize = 0;
        $tipeFile = '';

        if ($extension === 'pdf') {
            $maxSize = 10 * 1024; // 10MB
            $tipeFile = 'pdf';
        } elseif (in_array($extension, ['ppt', 'pptx'])) {
            $maxSize = 20 * 1024; // 20MB
            $tipeFile = $extension;
        } elseif (in_array($extension, ['jpg', 'jpeg', 'png', 'webp'])) {
            $maxSize = 5 * 1024; // 5MB
            $tipeFile = 'image';
        } else {
            return back()->withErrors(['file' => 'Format file tidak didukung. Harap upload file PDF, PPT, PPTX, atau Gambar (JPG, JPEG, PNG, WEBP).']);
        }

        if ($sizeKb > $maxSize) {
            $maxMb = $maxSize / 1024;
            return back()->withErrors(['file' => "Ukuran file untuk tipe ini tidak boleh melebihi {$maxMb}MB."]);
        }

        // Store file on public disk inside 'materi' folder
        $path = $file->store('materi', 'public');

        foreach ($request->kelas_ids as $clsId) {
            Materi::create([
                'judul' => $request->judul,
                'deskripsi' => $request->deskripsi,
                'mata_pelajaran_id' => $request->mata_pelajaran_id,
                'kelas_id' => $clsId,
                'guru_id' => auth()->id(),
                'nama_file' => $file->getClientOriginalName(),
                'path_file' => $path,
                'tipe_file' => $tipeFile,
                'ukuran_file' => $size,
                'status' => $request->status,
            ]);
        }

        $firstClassId = $request->kelas_ids[0];
        $redirectClassId = $request->input('redirect_kelas_id', $firstClassId);
        $redirectMapelId = $request->input('redirect_mapel_id', $request->mata_pelajaran_id);

        return $this->redirectToClassMateri($redirectClassId, $redirectMapelId)
            ->with('success', 'Materi berhasil diupload.');
    }

    /**
     * Display the specified resource.
     */
    public function show(Materi $materi): JsonResponse
    {
        if ($materi->guru_id !== auth()->id()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        return response()->json($materi->load(['kelas', 'mataPelajaran']));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Materi $materi): JsonResponse
    {
        if ($materi->guru_id !== auth()->id()) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        return response()->json($materi->load(['kelas', 'mataPelajaran']));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Materi $materi): RedirectResponse
    {
        if ($materi->guru_id !== auth()->id()) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'judul' => 'required|string|max:255',
            'mata_pelajaran_id' => 'required|exists:mata_pelajaran,id',
            'status' => 'required|in:aktif,draft',
            'deskripsi' => 'nullable|string',
            'file' => 'nullable|file',
            'edit_type' => 'required|in:global,local',
            'redirect_mapel_id' => 'nullable|exists:mata_pelajaran,id',
        ]);

        $originalPathFile = $materi->path_file;
        $originalNamaFile = $materi->nama_file;
        $originalTipeFile = $materi->tipe_file;
        $originalUkuranFile = $materi->ukuran_file;

        $newFileUploaded = false;
        if ($request->hasFile('file')) {
            $file = $request->file('file');
            $extension = strtolower($file->getClientOriginalExtension());
            $size = $file->getSize();
            $sizeKb = $size / 1024;

            $maxSize = 0;
            $tipeFile = '';

            if ($extension === 'pdf') {
                $maxSize = 10 * 1024;
                $tipeFile = 'pdf';
            } elseif (in_array($extension, ['ppt', 'pptx'])) {
                $maxSize = 20 * 1024;
                $tipeFile = $extension;
            } elseif (in_array($extension, ['jpg', 'jpeg', 'png', 'webp'])) {
                $maxSize = 5 * 1024;
                $tipeFile = 'image';
            } else {
                return back()->withErrors(['file' => 'Format file tidak didukung. Harap upload file PDF, PPT, PPTX, atau Gambar (JPG, JPEG, PNG, WEBP).']);
            }

            if ($sizeKb > $maxSize) {
                $maxMb = $maxSize / 1024;
                return back()->withErrors(['file' => "Ukuran file untuk tipe ini tidak boleh melebihi {$maxMb}MB."]);
            }

            // Store new file
            $path = $file->store('materi', 'public');
            $originalPathFile = $path;
            $originalNamaFile = $file->getClientOriginalName();
            $originalTipeFile = $tipeFile;
            $originalUkuranFile = $size;
            $newFileUploaded = true;
        }

        if ($request->edit_type === 'global') {
            // Find all shared records of this guru with original path_file
            $sharedMateriIds = Materi::where('guru_id', auth()->id())
                ->where('path_file', $materi->path_file)
                ->pluck('id')
                ->toArray();

            $updateData = [
                'judul' => $request->judul,
                'deskripsi' => $request->deskripsi,
                'mata_pelajaran_id' => $request->mata_pelajaran_id,
                'status' => $request->status,
                'nama_file' => $originalNamaFile,
                'path_file' => $originalPathFile,
                'tipe_file' => $originalTipeFile,
                'ukuran_file' => $originalUkuranFile,
            ];

            Materi::whereIn('id', $sharedMateriIds)->update($updateData);

            // Cleanup old file from storage if new one uploaded and no other record references it
            if ($newFileUploaded && $materi->path_file) {
                $otherCount = Materi::where('path_file', $materi->path_file)->count();
                if ($otherCount === 0) {
                    Storage::disk('public')->delete($materi->path_file);
                }
            }
        } else {
            // Edit Local: Decouple this single record.
            $judul = $request->judul;
            $kelasName = $materi->kelas->nama_kelas;
            if (!str_contains($judul, $kelasName)) {
                $judul .= " - " . $kelasName;
            }

            $updateData = [
                'judul' => $judul,
                'deskripsi' => $request->deskripsi,
                'mata_pelajaran_id' => $request->mata_pelajaran_id,
                'status' => $request->status,
                'nama_file' => $originalNamaFile,
                'path_file' => $originalPathFile,
                'tipe_file' => $originalTipeFile,
                'ukuran_file' => $originalUkuranFile,
            ];

            // If local edit uploaded a new file, we might need to delete old file if it was the last reference
            if ($newFileUploaded && $materi->path_file) {
                $otherCount = Materi::where('path_file', $materi->path_file)
                    ->where('id', '!=', $materi->id)
                    ->count();
                if ($otherCount === 0) {
                    Storage::disk('public')->delete($materi->path_file);
                }
            }

            $materi->update($updateData);
        }

        return $this->redirectToClassMateri($materi->kelas_id, $request->input('redirect_mapel_id', $request->mata_pelajaran_id))
            ->with('success', 'Materi berhasil diperbarui.');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Request $request, Materi $materi): RedirectResponse
    {
        if ($materi->guru_id !== auth()->id()) {
            abort(403, 'Unauthorized action.');
        }

        $kelasId = $materi->kelas_id;
        $mapelId = $request->input('redirect_mapel_id', $materi->mata_pelajaran_id);
        $pathFile = $materi->path_file;

        // Delete from database first
        $materi->delete();

        // Cleanup file from storage if no other records use it
        if ($pathFile) {
            $otherCount = Materi::where('path_file', $pathFile)->count();
            if ($otherCount === 0) {
                Storage::disk('public')->delete($pathFile);
            }
        }

        return $this->redirectToClassMateri($kelasId, $mapelId)
            ->with('success', 'Materi berhasil dihapus.');
    }

    private function redirectToClassMateri($kelasId, $mapelId = null): RedirectResponse
    {
        if ($mapelId) {
            return redirect()->route('guru.kelas.mapel.materi', [$kelasId, $mapelId]);
        }

        return redirect()->route('guru.kelas.materi', $kelasId);
    }

    /**
     * Download the specified resource file with its original name.
     */
    public function download(Materi $materi)
    {
        if ($materi->guru_id !== auth()->id()) {
            abort(403);
        }

        if (!Storage::disk('public')->exists($materi->path_file)) {
            return back()->with('error', 'File tidak ditemukan');
        }

        $path = storage_path('app/public/' . $materi->path_file);
        
        return response()->download($path, $materi->nama_file);
    }

    /**
     * Preview the specified resource file inline.
     */
    public function preview(Materi $materi)
    {
        if (!Storage::disk('public')->exists($materi->path_file)) {
            abort(404, 'File tidak ditemukan');
        }

        $path = Storage::disk('public')->path($materi->path_file);
        $mimeType = Storage::disk('public')->mimeType($materi->path_file);

        return response()->file($path, [
            'Content-Type' => $mimeType,
            'Content-Disposition' => 'inline; filename="' . $materi->nama_file . '"'
        ]);
    }
}
