<?php
// app/Http/Controllers/admin/RiwayatKegiatanController.php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\AbsensiKegiatan;
use App\Models\Kegiatan;
use App\Models\KategoriKegiatan;
use App\Models\Santri;
use App\Models\Kelas;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class RiwayatKegiatanController extends Controller
{
/**
     * Halaman utama riwayat — default: HARI INI
     *
     * Mode hari_ini     → flat list kegiatan (paginated cards)
     * Mode minggu_ini / custom → grouped by actual date, tiap tanggal = 1 tabel
     */
    public function index(Request $request)
    {
        $hariMap = [
            'Monday'   => 'Senin',  'Tuesday'  => 'Selasa', 'Wednesday' => 'Rabu',
            'Thursday' => 'Kamis',  'Friday'   => 'Jumat',  'Saturday'  => 'Sabtu',
            'Sunday'   => 'Ahad',
        ];

        // ── Tentukan mode & rentang tanggal ───────────────────────────────────
        $mode = $request->get('mode', 'hari_ini');

        if ($mode === 'minggu_ini') {
            $dari    = now()->startOfWeek(Carbon::MONDAY)->format('Y-m-d');
            $sampai  = now()->endOfWeek(Carbon::SUNDAY)->format('Y-m-d');
            $tanggal = null;
        } elseif ($mode === 'custom') {
            $dari    = $request->get('dari',   now()->subDays(6)->format('Y-m-d'));
            $sampai  = $request->get('sampai', now()->format('Y-m-d'));
            if ($dari > $sampai) { [$dari, $sampai] = [$sampai, $dari]; }
            $tanggal = null;
        } else {
            $mode    = 'hari_ini';
            $tanggal = $request->get('tanggal', now()->format('Y-m-d'));
            $dari    = $tanggal;
            $sampai  = $tanggal;
        }

        $kategoris  = KategoriKegiatan::select('kategori_id', 'nama_kategori')->orderBy('nama_kategori')->get();
        $kategoriId = $request->get('kategori_id', '');

        // ── Label periode ─────────────────────────────────────────────────────
        if ($mode === 'hari_ini') {
            $periodeLabel = Carbon::parse($dari)->locale('id')->isoFormat('dddd, D MMMM Y');
        } elseif ($mode === 'minggu_ini') {
            $periodeLabel = Carbon::parse($dari)->locale('id')->isoFormat('D MMM') . ' – '
                          . Carbon::parse($sampai)->locale('id')->isoFormat('D MMM Y');
        } else {
            $periodeLabel = Carbon::parse($dari)->locale('id')->isoFormat('D MMM Y') . ' – '
                          . Carbon::parse($sampai)->locale('id')->isoFormat('D MMM Y');
        }

        // ═══════════════════════════════════════════════════════════════════
        // MODE HARI INI — flat list kegiatan (paginated)
        // ═══════════════════════════════════════════════════════════════════
        if ($mode === 'hari_ini') {
            $hariDipilih = $hariMap[Carbon::parse($dari)->format('l')] ?? null;

            $baseQuery = Kegiatan::with(['kategori', 'kelasKegiatan.kelompok'])
                ->when($hariDipilih, fn($q) => $q->where('hari', $hariDipilih))
                ->when($kategoriId,  fn($q) => $q->where('kategori_id', $kategoriId))
                ->withCount([
                    'absensis as total_absensi' => fn($q) => $q->whereDate('tanggal', $dari),
                    'absensis as hadir'         => fn($q) => $q->where('status', 'Hadir')->whereDate('tanggal', $dari),
                    'absensis as terlambat'     => fn($q) => $q->where('status', 'Terlambat')->whereDate('tanggal', $dari),
                    'absensis as izin'          => fn($q) => $q->where('status', 'Izin')->whereDate('tanggal', $dari),
                    'absensis as sakit'         => fn($q) => $q->where('status', 'Sakit')->whereDate('tanggal', $dari),
                    'absensis as alpa'          => fn($q) => $q->where('status', 'Alpa')->whereDate('tanggal', $dari),
                    'absensis as pulang'        => fn($q) => $q->where('status', 'Pulang')->whereDate('tanggal', $dari),
                ])
                ->orderBy('waktu_mulai');

            $kegiatans          = (clone $baseQuery)->paginate(20)->appends($request->query());
            $kegiatanPerTanggal = null;

            $allItems = (clone $baseQuery)->get();
            $summary  = [
                'hadir'           => $allItems->sum('hadir') + $allItems->sum('terlambat'),
                'terlambat'       => $allItems->sum('terlambat'),
                'izin'            => $allItems->sum('izin'),
                'sakit'           => $allItems->sum('sakit'),
                'alpa'            => $allItems->sum('alpa'),
                'total_absensi'   => $allItems->sum('total_absensi'),
                'jumlah_kegiatan' => $allItems->count(),
                'jumlah_hari'     => 1,
            ];

        // ═══════════════════════════════════════════════════════════════════
        // MODE MULTI-HARI — grouped by actual date
        // ═══════════════════════════════════════════════════════════════════
        } else {
            $kegiatans = null;

            // Ambil semua tanggal yang ada absensi dalam range (terbaru dulu)
            $tanggalList = AbsensiKegiatan::selectRaw('DATE(tanggal) as tgl')
                ->whereDate('tanggal', '>=', $dari)
                ->whereDate('tanggal', '<=', $sampai)
                ->when($kategoriId, fn($q) => $q->whereHas('kegiatan', fn($qq) => $qq->where('kategori_id', $kategoriId)))
                ->groupBy('tgl')
                ->orderBy('tgl', 'desc')
                ->pluck('tgl');

            // Untuk tiap tanggal: kegiatan + stats khusus tanggal itu saja
            $kegiatanPerTanggal = collect();
            foreach ($tanggalList as $tgl) {
                $hariIndo = $hariMap[Carbon::parse($tgl)->format('l')] ?? null;

                $items = Kegiatan::with(['kategori', 'kelasKegiatan.kelompok'])
                    ->when($hariIndo,   fn($q) => $q->where('hari', $hariIndo))
                    ->when($kategoriId, fn($q) => $q->where('kategori_id', $kategoriId))
                    ->whereHas('absensis', fn($q) => $q->whereDate('tanggal', $tgl))
                    ->withCount([
                        'absensis as total_absensi' => fn($q) => $q->whereDate('tanggal', $tgl),
                        'absensis as hadir'         => fn($q) => $q->where('status', 'Hadir')->whereDate('tanggal', $tgl),
                        'absensis as terlambat'     => fn($q) => $q->where('status', 'Terlambat')->whereDate('tanggal', $tgl),
                        'absensis as izin'          => fn($q) => $q->where('status', 'Izin')->whereDate('tanggal', $tgl),
                        'absensis as sakit'         => fn($q) => $q->where('status', 'Sakit')->whereDate('tanggal', $tgl),
                        'absensis as alpa'          => fn($q) => $q->where('status', 'Alpa')->whereDate('tanggal', $tgl),
                        'absensis as pulang'        => fn($q) => $q->where('status', 'Pulang')->whereDate('tanggal', $tgl),
                    ])
                    ->orderBy('waktu_mulai')
                    ->get();

                if ($items->count() > 0) {
                    $kegiatanPerTanggal[$tgl] = $items;
                }
            }

            $allKeg  = $kegiatanPerTanggal->flatten();
            $summary = [
                'hadir'           => $allKeg->sum('hadir') + $allKeg->sum('terlambat'),
                'terlambat'       => $allKeg->sum('terlambat'),
                'izin'            => $allKeg->sum('izin'),
                'sakit'           => $allKeg->sum('sakit'),
                'alpa'            => $allKeg->sum('alpa'),
                'total_absensi'   => $allKeg->sum('total_absensi'),
                'jumlah_kegiatan' => $allKeg->count(),
                'jumlah_hari'     => $kegiatanPerTanggal->count(),
            ];
        }

        return view('admin.kegiatan.riwayat.index', compact(
            'kegiatans', 'kegiatanPerTanggal', 'kategoris', 'summary', 'mode',
            'dari', 'sampai', 'tanggal', 'periodeLabel', 'kategoriId'
        ));
    }

    /**
     * Detail riwayat per kegiatan — santri per kelas + filter
     */
    public function show($id, Request $request)
    {
        $kegiatan = Kegiatan::with(['kategori', 'kelasKegiatan.kelompok'])
            ->findOrFail($id);

        // ── Ambil parameter periode dari index ────────────────────────────────
        $mode    = $request->get('mode', 'hari_ini');
        $dari    = $request->get('dari',    now()->format('Y-m-d'));
        $sampai  = $request->get('sampai',  now()->format('Y-m-d'));
        $tanggal = $request->get('tanggal', now()->format('Y-m-d'));

        if ($mode === 'hari_ini') {
            $dari   = $tanggal;
            $sampai = $tanggal;
        }

        // ── Query absensi ─────────────────────────────────────────────────────
        $query = AbsensiKegiatan::with(['santri.kelasSantri.kelas.kelompok'])
            ->where('kegiatan_id', $kegiatan->kegiatan_id)
            ->whereDate('tanggal', '>=', $dari)
            ->whereDate('tanggal', '<=', $sampai);

        if ($request->filled('id_santri')) $query->where('id_santri', $request->id_santri);
        if ($request->filled('id_kelas'))  $query->whereHas('santri.kelasSantri', fn($q) => $q->where('id_kelas', $request->id_kelas));
        if ($request->filled('status'))    $query->where('status', $request->status);
        if ($request->filled('tanggal_spesifik')) $query->whereDate('tanggal', $request->tanggal_spesifik);

        $riwayats = $query->orderBy('tanggal', 'desc')->orderBy('waktu_absen')->paginate(50)->appends($request->query());

        // ── Statistik ─────────────────────────────────────────────────────────
        $statsQuery = AbsensiKegiatan::where('kegiatan_id', $kegiatan->kegiatan_id)
            ->whereDate('tanggal', '>=', $dari)->whereDate('tanggal', '<=', $sampai);
        if ($request->filled('id_kelas')) {
            $statsQuery->whereHas('santri.kelasSantri', fn($q) => $q->where('id_kelas', $request->id_kelas));
        }
        $stats = $statsQuery->select('status', DB::raw('count(*) as total'))
            ->groupBy('status')->pluck('total', 'status')->toArray();

        // ── Total santri yang seharusnya hadir ────────────────────────────────
        if ($kegiatan->kelasKegiatan->isEmpty()) {
            $totalSantriEligible = Santri::where('status', 'Aktif')->count();
        } else {
            $kelasIds = $kegiatan->kelasKegiatan->pluck('id')->toArray();
            $totalSantriEligible = Santri::where('status', 'Aktif')
                ->whereHas('kelasSantri', fn($q) => $q->whereIn('id_kelas', $kelasIds))
                ->count();
            if ($totalSantriEligible === 0) $totalSantriEligible = Santri::where('status', 'Aktif')->count();
        }

        $totalRecorded = array_sum($stats);
        $hadirCount    = ($stats['Hadir'] ?? 0) + ($stats['Terlambat'] ?? 0);
        $persenHadir   = $totalSantriEligible > 0 ? round($hadirCount / $totalSantriEligible * 100, 1) : 0;

        // ── Filter dropdown ───────────────────────────────────────────────────
        $santris   = Santri::where('status', 'Aktif')->select('id_santri', 'nama_lengkap')->orderBy('nama_lengkap')->get();
        $kelasList = Kelas::active()->ordered()->with('kelompok')->get();

        // ── Label periode ─────────────────────────────────────────────────────
        if ($mode === 'hari_ini') {
            $periodeLabel = Carbon::parse($dari)->locale('id')->isoFormat('dddd, D MMMM Y');
        } else {
            $periodeLabel = Carbon::parse($dari)->locale('id')->isoFormat('D MMM Y')
                          . ' – '
                          . Carbon::parse($sampai)->locale('id')->isoFormat('D MMM Y');
        }

        return view('admin.kegiatan.riwayat.show', compact(
            'kegiatan', 'riwayats', 'santris', 'kelasList', 'stats',
            'totalSantriEligible', 'totalRecorded', 'persenHadir',
            'mode', 'dari', 'sampai', 'tanggal', 'periodeLabel'
        ));
    }

    /**
     * Riwayat kehadiran per santri — tabbed per kategori
     */
    public function detailSantri($id_santri, Request $request)
    {
        $santri = Santri::where('id_santri', $id_santri)->firstOrFail();

        // ── Statistik ringkasan (Terlambat = Hadir, bukan Alpa) ──────────────
        $rawStats = AbsensiKegiatan::where('id_santri', $id_santri)
            ->select('status', DB::raw('count(*) as total'))
            ->groupBy('status')->pluck('total', 'status')->toArray();

        // Hadir efektif = Hadir + Terlambat
        $stats = $rawStats;
        $stats['_hadir_efektif'] = ($rawStats['Hadir'] ?? 0) + ($rawStats['Terlambat'] ?? 0);

        // ── Tren 30 hari — Hadir efektif (Hadir + Terlambat) ─────────────────
        $riwayat30Hari = AbsensiKegiatan::where('id_santri', $id_santri)
            ->whereDate('tanggal', '>=', now()->subDays(29))
            ->select(
                DB::raw('DATE(tanggal) as tanggal'),
                DB::raw('SUM(CASE WHEN status IN ("Hadir","Terlambat") THEN 1 ELSE 0 END) as hadir'),
                DB::raw('COUNT(*) as total')
            )
            ->groupBy('tanggal')->orderBy('tanggal', 'asc')->get();

        // ── Daftar semua kategori yang punya riwayat untuk santri ini ─────────
        $kategoriList = AbsensiKegiatan::where('id_santri', $id_santri)
            ->join('kegiatans', 'absensi_kegiatans.kegiatan_id', '=', 'kegiatans.kegiatan_id')
            ->join('kategori_kegiatans', 'kegiatans.kategori_id', '=', 'kategori_kegiatans.kategori_id')
            ->select(
                'kategori_kegiatans.kategori_id',
                'kategori_kegiatans.nama_kategori',
                DB::raw('COUNT(*) as total'),
                DB::raw('SUM(CASE WHEN absensi_kegiatans.status IN ("Hadir","Terlambat") THEN 1 ELSE 0 END) as hadir_efektif')
            )
            ->groupBy('kategori_kegiatans.kategori_id', 'kategori_kegiatans.nama_kategori')
            ->orderBy('kategori_kegiatans.nama_kategori')
            ->get();

        // ── Tab aktif & per_page ───────────────────────────────────────────────
        $activeKategori = $request->get('tab_kat', $kategoriList->first()?->kategori_id ?? '');

        // per_page: 15 | 50 | 100 | 'all' (semua data, tanpa paginasi)
        $perPageRaw = $request->get('per_page', 15);
        $showAll    = ($perPageRaw === 'all');
        $perPage    = $showAll ? 'all' : (in_array((int)$perPageRaw, [15, 50, 100]) ? (int)$perPageRaw : 15);

        // ── Riwayat untuk tab aktif ────────────────────────────────────────────
        $riwayatsQuery = AbsensiKegiatan::with('kegiatan.kategori')
            ->where('id_santri', $id_santri)
            ->whereHas('kegiatan', fn($q) => $q->where('kategori_id', $activeKategori))
            ->orderBy('tanggal', 'desc');

        if ($showAll) {
            // Wrap sebagai LengthAwarePaginator manual agar view tetap konsisten
            $allItems  = $riwayatsQuery->get();
            $riwayats  = new \Illuminate\Pagination\LengthAwarePaginator(
                $allItems, $allItems->count(), max($allItems->count(), 1), 1,
                ['path' => $request->url(), 'query' => $request->query()]
            );
        } else {
            $riwayats = $riwayatsQuery->paginate($perPage)->appends($request->query());
        }

        return view('admin.kegiatan.riwayat.detail-santri', compact(
            'santri', 'stats', 'riwayat30Hari', 'riwayats',
            'kategoriList', 'activeKategori', 'perPage', 'showAll'
        ));
    }

    public function edit(AbsensiKegiatan $riwayat)
    {
        $riwayat->load(['santri', 'kegiatan']);
        return view('admin.kegiatan.riwayat.edit', compact('riwayat'));
    }

    public function update(Request $request, AbsensiKegiatan $riwayat)
    {
        $validated = $request->validate([
            'status'      => 'required|in:Hadir,Izin,Sakit,Alpa,Terlambat,Pulang',
            'waktu_absen' => 'nullable|date_format:H:i',
        ]);
        $riwayat->update($validated);
        return redirect()->route('admin.riwayat-kegiatan.index')->with('success', 'Riwayat absensi berhasil diperbarui.');
    }

    public function destroy(AbsensiKegiatan $riwayat)
    {
        $nama = $riwayat->santri->nama_lengkap;
        $riwayat->delete();
        return redirect()->route('admin.riwayat-kegiatan.index')->with('success', "Riwayat absensi $nama berhasil dihapus.");
    }
}