<?php

namespace App\Http\Controllers;

use App\Models\Siswa;

use App\Models\Kelas;
use App\Models\TahunAjaran;
use App\Services\TagihanService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Spatie\SimpleExcel\SimpleExcelReader;
use App\Models\RiwayatStatusSiswa;
use Spatie\SimpleExcel\SimpleExcelWriter;

class SiswaController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index(Request $request)
{
    $tahunAktif = TahunAjaran::aktif()->first();

    $query = Siswa::select('siswa.*');

    // Set selectedTahunAjaranId fallback to active year
    $selectedTahunAjaranId = $request->filled('tahun_ajaran_id') ? $request->tahun_ajaran_id : ($tahunAktif ? $tahunAktif->id : null);

    if ($selectedTahunAjaranId) {
        // FILTER TAHUN AJARAN DAN KELAS (DARI SISWA_KELAS)
        // Gunakan siswaKelasHistory agar data tahun ajaran lama (nonaktif) ikut ditemukan
        $query->whereHas('siswaKelasHistory', function ($q) use ($selectedTahunAjaranId, $request) {
            $q->where('tahun_ajaran_id', $selectedTahunAjaranId);
            if ($request->filled('kelas_id')) {
                $q->where('kelas_id', $request->kelas_id);
            }
        });

        // EAGER LOAD SISWA_KELAS SPESIFIK TAHUN AJARAN TERSEBUT (termasuk historis)
        $query->with(['siswaKelasHistory' => function($q) use ($selectedTahunAjaranId) {
            $q->where('tahun_ajaran_id', $selectedTahunAjaranId)->with(['kelas', 'tahunAjaran']);
        }]);

        $query->leftJoin('siswa_kelas', function ($join) use ($selectedTahunAjaranId) {
            $join->on('siswa.id', '=', 'siswa_kelas.siswa_id')
                 ->where('siswa_kelas.tahun_ajaran_id', '=', $selectedTahunAjaranId);
        })->leftJoin('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id');
    } else {
        $query->with(['latestSiswaKelas.kelas', 'latestSiswaKelas.tahunAjaran']);

        $latestSiswaKelasQuery = DB::table('siswa_kelas')
            ->select('siswa_id', DB::raw('MAX(id) as latest_id'))
            ->groupBy('siswa_id');
            
        $query->leftJoinSub($latestSiswaKelasQuery, 'latest_sk', function($join) {
            $join->on('siswa.id', '=', 'latest_sk.siswa_id');
        })
        ->leftJoin('siswa_kelas', 'latest_sk.latest_id', '=', 'siswa_kelas.id')
        ->leftJoin('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id');
    }

    // GLOBAL SEARCH (NIS, Nama, WA, Kelas)
    if ($request->filled('search')) {
        $search = $request->search;
        $query->where(function ($q) use ($search) {
            $q->where('siswa.nama_lengkap', 'like', "%{$search}%")
              ->orWhere('siswa.nis', 'like', "%{$search}%")
              ->orWhere('siswa.no_wa', 'like', "%{$search}%")
              ->orWhereHas('siswaKelas.kelas', function ($kq) use ($search) {
             $kq->where('nama_kelas', 'like', "%{$search}%");
            });
        });
    }   // Optional filter by status
    if ($request->filled('status')) {
        $query->where('siswa.status', $request->status);
    }
    if ($request->filled('kategori')) {
    $query->where('siswa.kategori', $request->kategori);
    }

        $query->orderByRaw("
            CASE 
                WHEN kelas.jenjang = 'TK' THEN 1
                WHEN kelas.jenjang = 'SD' THEN 2
                WHEN kelas.jenjang = 'SMP' THEN 3
                WHEN kelas.jenjang = 'SMA' THEN 4
                ELSE 5
            END ASC
        ")
        ->orderByRaw("
            CASE 
                WHEN kelas.tingkat IS NULL THEN 'ZZZ'
                WHEN kelas.tingkat REGEXP '^[0-9]+$' THEN LPAD(kelas.tingkat, 3, '0') 
                ELSE UPPER(kelas.tingkat) 
            END ASC
        ")
        ->orderByRaw("
            CASE
                WHEN kelas.paralel IS NULL THEN 'ZZZ'
                ELSE UPPER(kelas.paralel)
            END ASC
        ")
        ->orderBy('siswa.nis', 'asc');

        $siswas = $query->paginate(15)->withQueryString();

        // Resolve selected values for Select2 UI persistence
        $selectedTa = $selectedTahunAjaranId ? \App\Models\TahunAjaran::find($selectedTahunAjaranId) : null;
        $selectedKelas = $request->filled('kelas_id') ? \App\Models\Kelas::find($request->kelas_id) : null;
        // Load all classes for filter dropdown
        $kelases = \App\Models\Kelas::orderBy('nama_kelas', 'asc')->get();

        return view('siswa.index', compact('siswas', 'tahunAktif', 'selectedTa', 'selectedKelas', 'kelases'));

    }

    public function store(Request $request)
    {
        $request->validate([
            'nis' => 'required|string|unique:siswa,nis',
            'nama_lengkap' => 'required|string|max:255',
            'kategori' => 'required|in:internal,external',
            'jenis_kelamin' => 'required|in:L,P',
            'no_wa' => 'nullable|string|max:20',
            // validate class and academic year for pivot
            'kelas_id' => 'required|exists:kelas,id',
            'tahun_ajaran_id' => 'required|exists:tahun_ajaran,id',
        ]);

        // Ensure class is active
        $kelasDetail = Kelas::aktif()->where('id', $request->kelas_id)->exists();
        if (!$kelasDetail) {
            return back()->with('error', 'Kelas yang Anda pilih tidak aktif atau tidak ditemukan.')->withInput();
        }

        DB::beginTransaction();
        try {
            // Create Siswa without class/year columns
            $siswa = Siswa::create([
                'nis' => $request->nis,
                'nama_lengkap' => $request->nama_lengkap,
                'kategori' => $request->kategori,
                'jenis_kelamin' => $request->jenis_kelamin,
                'no_wa' => $request->no_wa,
                'status' => 'aktif',
            ]);

            // Create pivot entry
            \App\Models\SiswaKelas::create([
                'siswa_id' => $siswa->id,
                'kelas_id' => $request->kelas_id,
                'tahun_ajaran_id' => $request->tahun_ajaran_id,
                'status' => 'aktif',
            ]);

            // Generate Tagihan for the student if the selected academic year is active
            $tahun = TahunAjaran::find($request->tahun_ajaran_id);
            if ($tahun && $tahun->status === 'aktif') {
                $kelas = Kelas::find($request->kelas_id);
                app(TagihanService::class)->generateTagihanSiswa($siswa, $kelas, $tahun);
            }

            DB::commit();
            return redirect()->route('siswa.index')->with('success', 'Data siswa berhasil ditambahkan.');
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Gagal menambahkan data siswa: ' . $e->getMessage())->withInput();
        }
    }

    public function update(Request $request, Siswa $siswa)
    {
        $request->validate([
            'nama_lengkap' => 'required|string|max:255',
            'kategori' => 'required|in:internal,external',
            'jenis_kelamin' => 'required|in:L,P',
            'no_wa' => 'nullable|string|max:20',
        ]);

        // Note: NIS is immutable as per requirement.

        $siswa->update([
            'nama_lengkap' => $request->nama_lengkap,
            'kategori' => $request->kategori,
            'jenis_kelamin' => $request->jenis_kelamin,
            'no_wa' => $request->no_wa,
        ]);

        return redirect()->route('siswa.index')->with('success', 'Data siswa berhasil diperbarui.');
    }



    public function downloadTemplate()
    {
        $path = storage_path('app/public/template_siswa.xlsx');
        
        $writer = SimpleExcelWriter::create($path);
        
        $writer->addRow([
            'NIS' => '1011',
            'Nama Lengkap' => 'Nurfitria',
            'Kategori' => 'external',
            'Jenis Kelamin' => 'P',
            'No WhatsApp' => '081326047272',
            'Nama Kelas' => 'A-1'
        ]);
        
        return response()->download($path, 'Template_Import_Siswa.xlsx')->deleteFileAfterSend(true);
    }

    public function importExcel(Request $request)
    {
        $request->validate([
            'file_excel' => 'required|mimes:xlsx,csv|max:5120', // Max 5MB
            'tahun_ajaran_id' => 'required|exists:tahun_ajaran,id',
        ]);

        $tahunAktif = TahunAjaran::find($request->tahun_ajaran_id);

        $file = $request->file('file_excel');
        
        try {
            $file = $request->file('file_excel');

            $path = $file->getRealPath();
            $extension = $file->getClientOriginalExtension();

            if ($extension === 'xlsx') {
                $reader = SimpleExcelReader::create($path, 'xlsx');
            } elseif ($extension === 'csv') {
                $reader = SimpleExcelReader::create($path, 'csv');
            } else {
                return back()->with('error', 'Format file tidak didukung');
            }

            $rows = $reader->getRows();

            $successCount = 0;
            $failedRows = [];
            DB::beginTransaction();
            
            $rows->each(function(array $rowProperties) use (&$successCount, &$failedRows, $tahunAktif) {

                $row = [];
                foreach ($rowProperties as $key => $value) {
                    $cleanKey = strtolower(trim($key));
                    $row[$cleanKey] = $value;
                }
                
                // Mapping column names loosely to handle minor inconsistencies
                $nis = trim($row['nis'] ?? null);
                $nama = trim($row['nama lengkap'] ?? null);
                $kategori = strtolower(trim($row['kategori'] ?? 'external'));
                $jk = strtoupper(trim($row['jenis kelamin'] ?? ''));
                $wa = trim($row['no whatsapp'] ?? null);
                $namaKelas = trim($row['nama kelas'] ?? null);

                $kelas = Kelas::aktif()
                    ->whereRaw('LOWER(TRIM(nama_kelas)) = ?', [strtolower(trim($namaKelas))])
                    ->first();

                $kelasId = $kelas->id ?? null;

                if (empty($nis) || empty($nama) || empty($kelasId)) {
                    $failedRows[] = "NIS {$nis}: Data kurang lengkap atau kelas tidak ditemukan.";
                    return;
                }
                if (!in_array($kategori, ['internal', 'external'])) {
                    $kategori = 'external';
                }

                if (!in_array($jk, ['L', 'P'])) {
                    $failedRows[] = "NIS {$nis}: Jenis kelamin tidak valid (Harus L atau P).";
                    return; // Skip row
                }

                // Check Class exists & active
                $kelasExist = Kelas::aktif()->where('id', $kelasId)->exists();
                if (!$kelasExist) {
                    $failedRows[] = "NIS {$nis}: Kelas dengan ID {$kelasId} tidak ditemukan atau sedang nonaktif.";
                    return; // Skip row
                }

                // Get or Create Siswa
                $siswa = Siswa::where('nis', $nis)->first();
                if ($siswa) {
                    $siswa->update([
                        'nama_lengkap' => $nama,
                        'kategori' => $kategori,
                        'jenis_kelamin' => $jk,
                        'no_wa' => $wa,
                    ]);
                } else {
                    $siswa = Siswa::create([
                        'nis' => $nis,
                        'nama_lengkap' => $nama,
                        'kategori' => $kategori,
                        'jenis_kelamin' => $jk,
                        'no_wa' => $wa,
                        'status' => 'aktif',
                    ]);
                }

                // Create pivot entry for class and academic year if not exists
                $alreadyAssigned = \App\Models\SiswaKelas::where('siswa_id', $siswa->id)
                    ->where('tahun_ajaran_id', $tahunAktif->id)
                    ->exists();

                if (!$alreadyAssigned) {
                    // Nonaktifkan kelas lain (sama seperti di kenaikan kelas)
                    \App\Models\SiswaKelas::where('siswa_id', $siswa->id)
                        ->where('tahun_ajaran_id', '!=', $tahunAktif->id)
                        ->update(['status' => 'nonaktif']);

                    \App\Models\SiswaKelas::create([
                        'siswa_id' => $siswa->id,
                        'kelas_id' => $kelasId,
                        'tahun_ajaran_id' => $tahunAktif->id,
                        'status' => 'aktif',
                    ]);

                    if ($tahunAktif->status === 'aktif') {
                        app(\App\Services\TagihanService::class)->generateTagihanSiswa($siswa, $kelas, $tahunAktif);
                    }
                }

                $successCount++;
            });
            
            DB::commit();

            if (count($failedRows) > 0) {
                // If there are failures, we pass them as flash message list
                return redirect()->route('siswa.index')->with([
                    'warning' => "Berhasil mengimpor {$successCount} data. Namun terdapat " . count($failedRows) . " baris gagal yang dilewati.",
                    'failed_rows' => $failedRows
                ]);
            }

            return redirect()->route('siswa.index')->with('success', "Berhasil mengimpor {$successCount} data siswa.");
            
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Terjadi kesalahan saat memproses file: ' . $e->getMessage());
        }
        }
        /**
    * Bulk toggle status for selected students.
    *
    * Expected request fields:
    *   - ids[]: array of siswa IDs
    *
    * Validates at least one ID is selected, then toggles status between
    * 'aktif' and 'tidak_aktif'. Other statuses are ignored.
    * Each change is logged to riwayat_status_siswa with admin_id.
    */
    public function bulkUpdateStatus(Request $request)
    {
        $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'exists:siswa,id',
        ]);

        $ids = $request->input('ids');
        $tahunAktif = TahunAjaran::aktif()->first();

        $updatedCount = 0;
        DB::beginTransaction();
        try {
            foreach ($ids as $siswaId) {
                $siswa = Siswa::find($siswaId);
                if (!$siswa) continue;
                $oldStatus = $siswa->status;
                // Determine new status
                if ($oldStatus === 'aktif') {
                    $newStatus = 'tidak_aktif';
                } elseif ($oldStatus === 'tidak_aktif') {
                    $newStatus = 'aktif';
                } else {
                    // Skip if status is not toggle-able (e.g., lulus)
                    continue;
                }
                // Update status
                $siswa->status = $newStatus;
                $siswa->save();

                if ($tahunAktif) {
                    \App\Models\SiswaKelas::withoutGlobalScope('active')
                        ->where('siswa_id', $siswa->id)
                        ->where('tahun_ajaran_id', $tahunAktif->id)
                        ->update(['status' => $newStatus]);
                }

                // Log to riwayat_status_siswa
                RiwayatStatusSiswa::create([
                    'siswa_id' => $siswa->id,
                    'tahun_ajaran_id' => $tahunAktif ? $tahunAktif->id : null,
                    'status_lama' => $oldStatus,
                    'status_baru' => $newStatus,
                    'keterangan' => 'toggle bulk',
                ]);
                $updatedCount++;
            }
            DB::commit();
            return redirect()->route('siswa.index')
                ->with('success', "Berhasil mengubah status {$updatedCount} siswa.");
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
        }
    }
public function updateStatus(Request $request, Siswa $siswa)
{
    $request->validate([
        'status' => 'required|in:aktif,tidak_aktif',
    ]);

    $oldStatus = $siswa->status;
    $newStatus = $request->status;

    // Hindari perubahan ke status yang sama
    if ($oldStatus === $newStatus) {
        return back()->with('info', 'Status siswa tidak berubah.');
    }

    $siswa->update([
        'status' => $newStatus,
    ]);

    $tahunAktif = TahunAjaran::aktif()->first();
    if ($tahunAktif) {
        \App\Models\SiswaKelas::withoutGlobalScope('active')
            ->where('siswa_id', $siswa->id)
            ->where('tahun_ajaran_id', $tahunAktif->id)
            ->update(['status' => $newStatus]);
    }

    RiwayatStatusSiswa::create([
        'siswa_id' => $siswa->id,
        'tahun_ajaran_id' => $tahunAktif?->id,
        'status_lama' => $oldStatus,
        'status_baru' => $newStatus,
        'keterangan' => 'toggle manual',
    ]);

    return redirect()->route('siswa.index')
        ->with('success', 'Status siswa berhasil diperbarui.');
}
}
