<?php

namespace App\Http\Controllers\Siswa;

use App\Http\Controllers\Controller;
use App\Models\Challenge;
use App\Models\PesertaChallenge;
use App\Models\Leaderboard;
use App\Services\BadgeService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class ChallengeController extends Controller
{
    public function index()
    {
        $siswa = Auth::guard('siswa')->user();

        $challenges = Challenge::whereHas('kelas', function ($q) use ($siswa) {
                $q->where('challenge_kelas.id_kelas', $siswa->id_kelas);
            })
            ->with(['soal'])
            ->withCount('soal')
            ->orderBy('tenggat_waktu', 'asc')
            ->get();

        $sudahDikerjakan = PesertaChallenge::where('id_siswa', $siswa->id_siswa)
            ->where('status', 'selesai')
            ->pluck('id_challenge')
            ->toArray();

        return view('siswa.challenge.index', compact('challenges', 'sudahDikerjakan'));
    }

    public function kerjakan($id_challenge)
    {
        $siswa = Auth::guard('siswa')->user();

        $challenge = Challenge::whereHas('kelas', function ($q) use ($siswa) {
                $q->where('challenge_kelas.id_kelas', $siswa->id_kelas);
            })
            ->with('soal')
            ->findOrFail($id_challenge);

        $sudah = PesertaChallenge::where('id_siswa', $siswa->id_siswa)
            ->where('id_challenge', $id_challenge)
            ->where('status', 'selesai')
            ->exists();

        if ($sudah) {
            return redirect()->route('siswa.challenge.hasil', $id_challenge);
        }

        if (Carbon::parse($challenge->tenggat_waktu)->isPast()) {
            return redirect()->route('siswa.challenge.index')
                ->with('error', 'Challenge ini sudah melewati tenggat waktu.');
        }

        if ($challenge->soal->isEmpty()) {
            return redirect()->route('siswa.challenge.index')
                ->with('error', 'Challenge ini belum memiliki soal.');
        }

        return view('siswa.challenge.kerjakan', compact('challenge'));
    }

    public function submit(Request $request, $id_challenge)
    {
        $siswa = Auth::guard('siswa')->user();

        $challenge = Challenge::whereHas('kelas', function ($q) use ($siswa) {
                $q->where('challenge_kelas.id_kelas', $siswa->id_kelas);
            })
            ->with('soal')
            ->findOrFail($id_challenge);

        $sudah = PesertaChallenge::where('id_siswa', $siswa->id_siswa)
            ->where('id_challenge', $id_challenge)
            ->where('status', 'selesai')
            ->exists();

        if ($sudah) {
            return redirect()->route('siswa.challenge.hasil', $id_challenge);
        }

        if (Carbon::parse($challenge->tenggat_waktu)->isPast()) {
            return redirect()->route('siswa.challenge.index')
                ->with('error', 'Challenge sudah melewati tenggat waktu.');
        }

        $jawaban     = $request->input('jawaban', []);
        $totalExp    = 0;
        $jawabanJson = [];

        foreach ($challenge->soal as $soal) {
            $jwb = $jawaban[$soal->id_soal] ?? null;
            $jawabanJson[$soal->id_soal] = $jwb;
            if ($jwb && strtoupper($jwb) === strtoupper($soal->jawaban_benar)) {
                $totalExp += $soal->exp_per_soal;
            }
        }

        $now         = Carbon::now();
        $semester    = $now->month >= 7 ? '1' : '2';
        $tahunAjaran = $now->month >= 7
            ? $now->year . '/' . ($now->year + 1)
            : ($now->year - 1) . '/' . $now->year;

        DB::transaction(function () use ($siswa, $challenge, $jawabanJson, $totalExp, $semester, $tahunAjaran) {
            PesertaChallenge::create([
                'id_challenge' => $challenge->id_challenge,
                'id_siswa'     => $siswa->id_siswa,
                'jawaban'      => json_encode($jawabanJson),
                'waktu_submit' => Carbon::now(),
                'exp'          => $totalExp,
                'status'       => 'selesai',
            ]);

            $lb = Leaderboard::firstOrCreate(
                [
                    'id_siswa'     => $siswa->id_siswa,
                    'id_kelas'     => $siswa->id_kelas,
                    'semester'     => $semester,
                    'tahun_ajaran' => $tahunAjaran,
                ],
                ['total_exp' => 0, 'ranking' => 0]
            );

            $lb->increment('total_exp', $totalExp);

            Leaderboard::where('id_kelas', $siswa->id_kelas)
                ->where('semester', $semester)
                ->where('tahun_ajaran', $tahunAjaran)
                ->orderBy('total_exp', 'desc')
                ->get()
                ->each(fn($row, $i) => $row->update(['ranking' => $i + 1]));
        });

        // --- Cek & berikan badge challenge (di luar transaksi agar tidak block) ---
        app(BadgeService::class)->checkChallengeBadges($siswa->id_siswa);

        return redirect()->route('siswa.challenge.hasil', $id_challenge);
    }

    public function hasil($id_challenge)
    {
        $siswa = Auth::guard('siswa')->user();

        $challenge = Challenge::with('soal')->findOrFail($id_challenge);

        $peserta = PesertaChallenge::where('id_siswa', $siswa->id_siswa)
            ->where('id_challenge', $id_challenge)
            ->firstOrFail();

        $jawabanSiswa = json_decode($peserta->jawaban, true) ?? [];

        $benar = 0; $salah = 0;
        foreach ($challenge->soal as $soal) {
            $jwb = $jawabanSiswa[$soal->id_soal] ?? null;
            strtoupper((string)$jwb) === strtoupper($soal->jawaban_benar) ? $benar++ : $salah++;
        }

        $totalSoal  = $challenge->soal->count();
        $persentase = $totalSoal > 0 ? round(($benar / $totalSoal) * 100) : 0;

        return view('siswa.challenge.hasil', compact(
            'challenge', 'peserta', 'jawabanSiswa',
            'benar', 'salah', 'totalSoal', 'persentase'
        ));
    }
}