<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\PengerjaanUjian;
use App\Models\PelanggaranUjian;
use App\Models\Ujian;
use App\Models\NilaiUjian;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;

class PengerjaanUjianController extends Controller
{
    // Siswa: ambil daftar ujian aktif hari ini untuk kelas siswa
    public function ujianSaya(Request $request)
    {
        $siswa = $request->user()->siswa;

        if (!$siswa) {
            return response()->json(['success' => false, 'message' => 'Profil siswa tidak ditemukan.'], 404);
        }

        $today = Carbon::today();

        $ujianList = Ujian::with(['mataPelajaran', 'kelas'])
            ->where('kelas_id', $siswa->kelas_id)
            ->where('status', 'aktif')
            ->whereDate('tanggal_mulai', '<=', $today)
            ->whereDate('tanggal_selesai', '>=', $today)
            ->get()
            ->map(function ($ujian) use ($siswa) {
                $pengerjaan = PengerjaanUjian::where('ujian_id', $ujian->id)
                    ->where('siswa_id', $siswa->id)
                    ->first();

                $ujian->pengerjaan = $pengerjaan;
                return $ujian;
            });

        return response()->json(['success' => true, 'data' => $ujianList]);
    }

    // Siswa: mulai mengerjakan ujian
    public function mulai(Request $request, Ujian $ujian)
    {
        $siswa = $request->user()->siswa;

        if (!$siswa) {
            return response()->json(['success' => false, 'message' => 'Profil siswa tidak ditemukan.'], 404);
        }

        if ($ujian->status !== 'aktif') {
            return response()->json(['success' => false, 'message' => 'Ujian tidak aktif.'], 422);
        }

        if ($ujian->kelas_id !== $siswa->kelas_id) {
            return response()->json(['success' => false, 'message' => 'Anda tidak berhak mengikuti ujian ini.'], 403);
        }

        $pengerjaan = PengerjaanUjian::where('ujian_id', $ujian->id)
            ->where('siswa_id', $siswa->id)
            ->first();

        // Cek locked
        if ($pengerjaan && $pengerjaan->is_locked) {
            return response()->json(['success' => false, 'message' => 'Ujian Anda terkunci karena pelanggaran. Hubungi pengawas.'], 403);
        }

        // Jika sudah selesai
        if ($pengerjaan && $pengerjaan->status === 'selesai') {
            return response()->json(['success' => false, 'message' => 'Anda sudah menyelesaikan ujian ini.'], 422);
        }

        // Buat atau lanjutkan pengerjaan
        if (!$pengerjaan) {
            $pengerjaan = PengerjaanUjian::create([
                'ujian_id'    => $ujian->id,
                'siswa_id'    => $siswa->id,
                'waktu_mulai' => now(),
                'status'      => 'sedang',
            ]);
        } elseif ($pengerjaan->status === 'direset') {
            $pengerjaan->update(['status' => 'sedang', 'waktu_mulai' => now(), 'waktu_selesai' => null]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Ujian dimulai.',
            'data'    => [
                'pengerjaan'       => $pengerjaan,
                'ujian'            => $ujian->load('mataPelajaran'),
                'link_google_form' => $ujian->link_google_form,
                'durasi_menit'     => $ujian->durasi_menit,
                'waktu_mulai'      => $pengerjaan->waktu_mulai,
                'sisa_waktu_detik' => $this->hitungSisaWaktu($pengerjaan, $ujian),
            ],
        ]);
    }

    // Siswa: selesaikan ujian
    public function selesai(Request $request, Ujian $ujian)
    {
        $siswa = $request->user()->siswa;

        if (!$siswa) {
            return response()->json(['success' => false, 'message' => 'Profil siswa tidak ditemukan.'], 404);
        }

        $pengerjaan = PengerjaanUjian::where('ujian_id', $ujian->id)
            ->where('siswa_id', $siswa->id)
            ->first();

        if (!$pengerjaan) {
            return response()->json(['success' => false, 'message' => 'Pengerjaan tidak ditemukan.'], 404);
        }

        // Jika sudah selesai sebelumnya (double-submit), anggap sukses
        if ($pengerjaan->status === 'selesai') {
            return response()->json(['success' => true, 'message' => 'Ujian sudah diselesaikan.', 'data' => $pengerjaan]);
        }

        // Status tidak valid (misal: direset tapi belum mulai lagi)
        if ($pengerjaan->status !== 'sedang') {
            return response()->json(['success' => false, 'message' => 'Status pengerjaan tidak valid.'], 422);
        }

        $pengerjaan->update([
            'status'        => 'selesai',
            'waktu_selesai' => now(),
        ]);

        // Buat record nilai jika belum ada
        NilaiUjian::firstOrCreate([
            'ujian_id' => $ujian->id,
            'siswa_id' => $siswa->id,
        ]);

        return response()->json(['success' => true, 'message' => 'Ujian berhasil diselesaikan.', 'data' => $pengerjaan]);
    }

    // Siswa: log pelanggaran
    public function logPelanggaran(Request $request, Ujian $ujian)
    {
        $request->validate([
            'jenis'      => 'required|in:klik_kanan,pindah_tab,buka_tab_baru,keluar_fullscreen,shortcut_terlarang',
            'keterangan' => 'nullable|string|max:255',
        ]);

        $siswa = $request->user()->siswa;

        $pengerjaan = PengerjaanUjian::where('ujian_id', $ujian->id)
            ->where('siswa_id', $siswa->id)
            ->where('status', 'sedang')
            ->first();

        if (!$pengerjaan) {
            return response()->json(['success' => false, 'message' => 'Pengerjaan tidak aktif.'], 404);
        }

        // Log pelanggaran
        PelanggaranUjian::create([
            'pengerjaan_ujian_id' => $pengerjaan->id,
            'jenis'               => $request->jenis,
            'waktu'               => now(),
            'keterangan'          => $request->keterangan,
        ]);

        // Increment counter
        $pengerjaan->increment('jumlah_pelanggaran');
        $pengerjaan->refresh();

        $isLocked = false;
        if ($pengerjaan->jumlah_pelanggaran >= 3) {
            $pengerjaan->update(['is_locked' => true, 'status' => 'selesai', 'waktu_selesai' => now()]);
            $isLocked = true;
        }

        return response()->json([
            'success'            => true,
            'jumlah_pelanggaran' => $pengerjaan->jumlah_pelanggaran,
            'is_locked'          => $isLocked,
            'message'            => $isLocked
                ? 'Ujian Anda dikunci karena melebihi batas pelanggaran.'
                : 'Pelanggaran dicatat. Peringatan ke-' . $pengerjaan->jumlah_pelanggaran . '/3.',
        ]);
    }

    // Admin/Superadmin: reset pengerjaan siswa
    public function reset(Request $request, PengerjaanUjian $pengerjaanUjian)
    {
        $request->validate([
            'catatan_reset' => 'nullable|string|max:500',
        ]);

        $pengerjaanUjian->update([
            'status'             => 'direset',
            'is_locked'          => false,
            'jumlah_pelanggaran' => 0,
            'waktu_selesai'      => null,
            'catatan_reset'      => $request->catatan_reset ?? 'Reset oleh admin.',
        ]);

        return response()->json(['success' => true, 'message' => 'Pengerjaan ujian siswa berhasil direset.', 'data' => $pengerjaanUjian]);
    }

    // Admin/Superadmin: monitoring semua pengerjaan
    public function monitoring(Request $request)
    {
        $query = PengerjaanUjian::with(['ujian.mataPelajaran', 'ujian.kelas', 'siswa.kelas'])
            ->when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))
            ->when($request->status,   fn($q) => $q->where('status', $request->status))
            ->when($request->kelas_id, fn($q) =>
                $q->whereHas('ujian', fn($u) => $u->where('kelas_id', $request->kelas_id))
            )
            ->when($request->is_locked, fn($q) => $q->where('is_locked', true))
            ->when($request->search,    fn($q) => $q->whereHas('siswa', fn($s) =>
                $s->where('nama', 'like', '%' . $request->search . '%')
            ))
            ->orderByDesc('updated_at');

        $perPage = min((int) $request->get('per_page', 25), 200);
        $data    = $query->paginate($perPage);

        // Summary stats
        $summary = [
            'total'   => PengerjaanUjian::when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))->count(),
            'sedang'  => PengerjaanUjian::when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))->where('status', 'sedang')->count(),
            'selesai' => PengerjaanUjian::when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))->where('status', 'selesai')->count(),
            'belum'   => PengerjaanUjian::when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))->where('status', 'belum')->count(),
            'locked'  => PengerjaanUjian::when($request->ujian_id, fn($q) => $q->where('ujian_id', $request->ujian_id))->where('is_locked', true)->count(),
        ];

        return response()->json(['success' => true, 'data' => $data, 'summary' => $summary]);
    }

    // Riwayat ujian (semua role)
    public function riwayat(Request $request)
    {
        $user  = $request->user();
        $query = PengerjaanUjian::with(['ujian.mataPelajaran', 'ujian.kelas', 'siswa', 'pelanggaran']);

        if ($user->isSiswa()) {
            $query->where('siswa_id', $user->siswa->id);
        } elseif ($user->isGuru()) {
            $guru = $user->guru;
            $guruMengajarIds = $guru ? $guru->guruMengajar->pluck('id') : [];
            $query->whereHas('ujian', fn($q) => $q->whereIn('guru_mengajar_id', $guruMengajarIds));
        }

        $query
            ->when($request->ujian_id,  fn($q) => $q->where('ujian_id', $request->ujian_id))
            ->when($request->status,    fn($q) => $q->where('status', $request->status))
            ->when($request->is_locked, fn($q) => $q->where('is_locked', true))
            ->when($request->search,    fn($q) => $q->whereHas('siswa', fn($s) =>
                $s->where('nama', 'like', '%' . $request->search . '%')
            ));

        $summary = [
            'total'             => (clone $query)->count(),
            'selesai'           => (clone $query)->where('status', 'selesai')->count(),
            'locked'            => (clone $query)->where('is_locked', true)->count(),
            'total_pelanggaran' => (clone $query)->sum('jumlah_pelanggaran'),
        ];

        $perPage = min((int) $request->get('per_page', 20), 200);
        $data    = $query->orderByDesc('updated_at')->paginate($perPage);

        return response()->json(['success' => true, 'data' => $data, 'summary' => $summary]);
    }

    private function hitungSisaWaktu(PengerjaanUjian $pengerjaan, Ujian $ujian): int
    {
        if (!$pengerjaan->waktu_mulai) return $ujian->durasi_menit * 60;

        $waktuHabis = $pengerjaan->waktu_mulai->addMinutes($ujian->durasi_menit);
        $sisaDetik  = now()->diffInSeconds($waktuHabis, false);

        return max(0, (int) $sisaDetik);
    }
}
