<?php

namespace App\Http\Controllers;

use App\Models\Kelas;
use App\Models\Siswa;
use App\Models\Tagihan;
use App\Models\TahunAjaran;
use App\Models\TransaksiPembayaran;

use Illuminate\Http\Request;
use Spatie\SimpleExcel\SimpleExcelWriter;

class LaporanController extends Controller
{
    /**
     * Bangun query dasar untuk laporan pembayaran dengan filter.
     */
    private function buildQueryPembayaran(Request $request)
    {
        $query = TransaksiPembayaran::with(['siswa', 'user', 'tahunAjaran', 'detailPembayaran.tagihan'])
            ->orderBy('tanggal_bayar', 'desc');

        if ($request->nis) {
            $query->whereHas('siswa', fn($q) => $q->where('nis', $request->nis));
        }
        if ($request->tingkat) {
            $query->whereHas('siswa.siswaKelas.kelas', fn($q) => $q->where('tingkat', $request->tingkat));
        }
        if ($request->tahun_ajaran_id) {
            $query->where('tahun_ajaran_id', $request->tahun_ajaran_id);
        }
        if ($request->tanggal_mulai && $request->tanggal_sampai) {
            $query->whereBetween('tanggal_bayar', [$request->tanggal_mulai, $request->tanggal_sampai]);
        }
        // Filter jenis pembayaran SPP/DPP via tagihan terkait
        if ($request->jenis_pembayaran) {
            $jenis = $request->jenis_pembayaran;
            $query->whereHas('detailPembayaran.tagihan.tarifPembayaran', fn($q) => $q->where('jenis', $jenis));
        }

        // Restrict Wali Kelas to their kelas
        if (auth()->user() && auth()->user()->hasRole('wali_kelas')) {
            $myKelasId = auth()->user()->kelas_id;
           $query->whereHas('siswa.siswaKelas', function ($q) use ($myKelasId) {
            $q->where('kelas_id', $myKelasId);
        });
        } elseif (auth()->user() && auth()->user()->hasRole('kepala_sekolah')) {
            $myJenjang = auth()->user()->jenjang;
            $query->whereHas('siswa.kelas', fn($q) => $q->where('jenjang', $myJenjang));
        }

        return $query;
    }

    /**
     * Bangun query dasar untuk laporan tagihan dengan filter.
     */
    private function buildQueryTagihan(Request $request)
    {
        $query = Tagihan::with(['siswa', 'kelas', 'tahunAjaran'])->orderBy('tanggal_jatuh_tempo', 'desc');

        if ($request->nis) {
            $query->whereHas('siswa', fn($q) => $q->where('nis', $request->nis));
        }
        if ($request->tingkat) {
            $query->whereHas('kelas', fn($q) => $q->where('tingkat', $request->tingkat));
        }
        if ($request->tahun_ajaran_id) {
            $query->where('tahun_ajaran_id', $request->tahun_ajaran_id);
        }
        if ($request->status) {
            if ($request->status === 'tunggakan') {
                $query->tunggakan();
            } else {
                $query->where('tagihan.status', $request->status);
            }
        }
        if ($request->bulan) {
            $query->where('bulan', $request->bulan);
        }
        if ($request->jenis_tagihan) {
            $jenis = $request->jenis_tagihan;
            $query->whereHas('tarifPembayaran', fn($q) => $q->where('jenis', $jenis));
        }

        // Restrict Wali Kelas to their kelas
        if (auth()->user() && auth()->user()->hasRole('wali_kelas')) {
            $myKelasId = auth()->user()->kelas_id;
            $query->whereHas('siswa.siswaKelas', function ($q) use ($myKelasId) {
            $q->where('kelas_id', $myKelasId);
        });
        } elseif (auth()->user() && auth()->user()->hasRole('kepala_sekolah')) {
            $myJenjang = auth()->user()->jenjang;
            $query->whereHas('kelas', fn($q) => $q->where('jenjang', $myJenjang));
        }

        return $query;
    }

    public function index(Request $request)
    {
        $tahunAjarans = TahunAjaran::orderBy('tahun', 'desc')->get();
        $isWaliKelas = auth()->user()->hasRole('wali_kelas');
        $isKepalaSekolah = auth()->user()->hasRole('kepala_sekolah');
        $kepalaSekolahJenjang = $isKepalaSekolah ? auth()->user()->jenjang : null;

        $kelases = $kepalaSekolahJenjang
            ? Kelas::where('jenjang', $kepalaSekolahJenjang)->orderBy('tingkat')->orderBy('paralel')->orderBy('nama_kelas')->get()
            : Kelas::orderBy('jenjang')->orderBy('tingkat')->orderBy('nama_kelas')->get();
        
        $tab = $request->query('tab', 'spp');

        if (auth()->user()->hasAnyRole(['wali_kelas', 'kepala_sekolah']) && $tab === 'harian') {
            abort(403, 'Akses tidak diizinkan untuk melihat laporan harian.');
        }

        // Otomatis set filter & tahun ajaran aktif jika belum ada agar data langsung tampil
        if (!$request->has('filter')) {
            $request->merge(['filter' => '1']);
        }
        if (!$request->has('tahun_ajaran_id')) {
            $defaultTahun = TahunAjaran::aktif()->first() ?? TahunAjaran::orderBy('tahun', 'desc')->first();
            if ($defaultTahun) {
                $request->merge(['tahun_ajaran_id' => $defaultTahun->id]);
            }
        }

        // Default or filter variables
        $siswaKelasList = new \Illuminate\Pagination\LengthAwarePaginator([], 0, 15);
        $rekapTagihans = collect();
        $bulanList = [];
        $tahunAwal = null;
        $activeTahunAjaranId = 0;
        $selectedTahunAjaran = null;

        // Query Preview Rekap Pembayaran (SPP atau DPP) dan Laporan Tagihan
        if ($tab === 'spp' || $tab === 'dpp' || $tab === 'tagihan' || $tab === 'riwayat') {
            $tahunAjaranId = $request->tahun_ajaran_id ?: (TahunAjaran::aktif()->first()?->id ?? TahunAjaran::orderBy('tahun', 'desc')->first()?->id);
            $selectedTahunAjaran = TahunAjaran::find($tahunAjaranId);
             if ($selectedTahunAjaran) {
         $siswaKelasQuery = \App\Models\SiswaKelas::withoutGlobalScope('active')
            ->with(['siswa', 'kelas'])
            ->where('siswa_kelas.tahun_ajaran_id', $tahunAjaranId)
            ->whereHas('siswa', function ($q) {
            $q->where('siswa.status', 'aktif');
        })
                ->join('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id')
                ->orderBy('kelas.jenjang')
                ->orderBy('kelas.tingkat')
                ->orderBy('kelas.paralel')
                ->select('siswa_kelas.*');
             
                    if ($isWaliKelas) {
                        $myKelasId = auth()->user()->kelas_id;
                        $siswaKelasQuery->where('siswa_kelas.kelas_id', $myKelasId);
                    } elseif ($kepalaSekolahJenjang) {
                        // Kepala sekolah: otomatis filter jenjang, tidak perlu input manual
                        $siswaKelasQuery->where('kelas.jenjang', $kepalaSekolahJenjang);
                    } elseif ($request->jenjang) {
                        $siswaKelasQuery->where('kelas.jenjang', $request->jenjang);
                    }

                if ($request->tingkat) {
                    $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('tingkat', $request->tingkat));
                }
                if ($request->paralel) {
                    $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('paralel', $request->paralel));
                }
                if ($request->nis) {
                    $siswaKelasQuery->whereHas('siswa', function ($q) use ($request) {
                    $q->where('nis', $request->nis);
                     });

                }
                $siswaKelasList = $siswaKelasQuery->get();

                $siswaIds = $siswaKelasList
                ->pluck('siswa_id')
                ->toArray();
                
                // Fetch tagihans
                $rekapTagihansQuery = Tagihan::with('tarifPembayaran')
                    ->whereIn('siswa_id', $siswaIds)
                    ->where(function ($q) use ($tahunAjaranId) {
                        $q->where('tahun_ajaran_id', $tahunAjaranId)
                          ->orWhere(function ($q2) use ($tahunAjaranId) {
                              $q2->whereHas('tarifPembayaran', fn($t) => $t->where('jenis', 'DPP'))
                                 ->where('tahun_ajaran_id', '!=', $tahunAjaranId)
                                 ->where('status', '!=', 'lunas');
                          });
                    })
                    ->get();

                $rekapTagihans = $rekapTagihansQuery->filter(function($t) use ($siswaKelasList, $tahunAjaranId) {
                    if ($t->tahun_ajaran_id == $tahunAjaranId) return true;
                    $sk = $siswaKelasList->firstWhere('siswa_id', $t->siswa_id);
                    $jenjang = $sk && $sk->kelas ? $sk->kelas->jenjang : null;
                    return $t->tarifPembayaran && $t->tarifPembayaran->jenjang === $jenjang;
                })->groupBy('siswa_id');

                $bulanList = $selectedTahunAjaran->getBulanSppList();
                $tahunAwal = (int) substr($selectedTahunAjaran->tahun, 0, 4);
                $activeTahunAjaran = TahunAjaran::aktif()->first();
                $activeTahunAjaranId = $activeTahunAjaran ? $activeTahunAjaran->id : 0;
            }
        }

        $tagihans = $this->buildQueryTagihan($request)->get();
        // Data tagihan kini tergabung dalam query di atas

        // Query Riwayat Pembayaran Siswa
        $riwayatTransaksi = collect();
        if ($tab === 'riwayat' && isset($siswaIds) && $selectedTahunAjaran) {
            $riwayatTransaksi = TransaksiPembayaran::with(['detailPembayaran.tagihan.tarifPembayaran', 'user'])
                ->whereIn('siswa_id', $siswaIds)
                ->where('tahun_ajaran_id', $tahunAjaranId)
                ->orderBy('tanggal_bayar', 'asc')
                ->orderBy('created_at', 'asc')
                ->get()
                ->groupBy('siswa_id');
        }

        // Query Preview Harian
        
        $transaksiHarian = collect();
        $tanggalHarian = $request->tanggal ?? now()->format('Y-m-d');
        if ($tab === 'harian' && $request->has('filter')) {
            $queryHarian = TransaksiPembayaran::with(['siswa', 'user', 'detailPembayaran.tagihan'])
                ->whereDate('tanggal_bayar', $tanggalHarian)
                ->orderBy('created_at', 'desc');
            // Apply year filter based on selected tahun ajaran (fallback to active year)
            $filterTahunAjaranId = $request->tahun_ajaran_id ?? ($selectedTahunAjaran->id ?? null);
            if ($filterTahunAjaranId) {
                $queryHarian->where('tahun_ajaran_id', $filterTahunAjaranId);
            }

            // Apply payment method filter if provided
            if ($request->metode_pembayaran) {
                $queryHarian->where('metode_pembayaran', $request->metode_pembayaran);
            }

            if ($isWaliKelas) {
                $myKelasId = auth()->user()->kelas_id;
               $queryHarian->whereHas('siswa', fn($q) => $q->where('kelas_id', $myKelasId));
            } elseif ($kepalaSekolahJenjang) {
                $queryHarian->whereHas('siswa.kelas', fn($q) => $q->where('jenjang', $kepalaSekolahJenjang));
            }

            $transaksiHarian = $queryHarian->get();
        }
                return view('laporan.index', compact(
            'tahunAjarans', 'kelases', 'tab', 'tagihans',
            'siswaKelasList', 'rekapTagihans', 'selectedTahunAjaran',
            'bulanList', 'tahunAwal', 'activeTahunAjaranId', 'isWaliKelas',
            'isKepalaSekolah', 'kepalaSekolahJenjang', 'transaksiHarian', 'tanggalHarian',
            'riwayatTransaksi'
        ));
    }

    public function exportPembayaran(Request $request)
    {
        // Tentukan tahun ajaran terpilih
        $tahunAjaranId = $request->tahun_ajaran_id ?: (TahunAjaran::aktif()->first()?->id ?? TahunAjaran::orderBy('tahun', 'desc')->first()?->id);
        $selectedTahunAjaran = TahunAjaran::find($tahunAjaranId);

        if (!$selectedTahunAjaran) {
            return back()->with('error', 'Tahun ajaran tidak valid.');
        }

        // Build query without SiswaKelas — gunakan withoutGlobalScope agar data historis tampil
        $siswaKelasQuery = \App\Models\SiswaKelas::withoutGlobalScope('active')
        ->with(['siswa', 'kelas'])
        ->where('siswa_kelas.tahun_ajaran_id', $tahunAjaranId)
        ->whereHas('siswa', function ($q) {
        $q->where('siswa.status', 'aktif');
    })
        ->join('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id')
        ->orderBy('kelas.jenjang')
        ->orderBy('kelas.tingkat')
        ->orderBy('kelas.paralel')
        ->select('siswa_kelas.*');

        if (auth()->user()->hasRole('wali_kelas')) {
            $siswaKelasQuery->where('siswa_kelas.kelas_id', auth()->user()->kelas_id);
        } elseif (auth()->user()->hasRole('kepala_sekolah')) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', auth()->user()->jenjang));
        } elseif ($request->jenjang) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', $request->jenjang));
        }

        if ($request->tingkat) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('tingkat', $request->tingkat));
        }
        if ($request->paralel) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('paralel', $request->paralel));
        }
        if ($request->nis) {
            $siswaKelasQuery->whereHas('siswa', fn($q) => $q->where('nis', $request->nis));
        }

        $siswaKelasList = $siswaKelasQuery->get();

        $siswaIds = $siswaKelasList->pluck('siswa_id')->toArray();

        // Eager load tagihans
        $rekapTagihansQuery = Tagihan::with('tarifPembayaran')
            ->whereIn('siswa_id', $siswaIds)
            ->where(function ($q) use ($tahunAjaranId) {
                $q->where('tahun_ajaran_id', $tahunAjaranId)
                  ->orWhere(function ($q2) use ($tahunAjaranId) {
                      $q2->whereHas('tarifPembayaran', fn($t) => $t->where('jenis', 'DPP'))
                         ->where('tahun_ajaran_id', '!=', $tahunAjaranId)
                         ->where('status', '!=', 'lunas');
                  });
            })
            ->get();

        $rekapTagihans = $rekapTagihansQuery->filter(function($t) use ($siswaKelasList, $tahunAjaranId) {
            if ($t->tahun_ajaran_id == $tahunAjaranId) return true;
            $sk = $siswaKelasList->firstWhere('siswa_id', $t->siswa_id);
            $jenjang = $sk && $sk->kelas ? $sk->kelas->jenjang : null;
            return $t->tarifPembayaran && $t->tarifPembayaran->jenjang === $jenjang;
        })->groupBy('siswa_id');

        $jenisPembayaran = $request->jenis_pembayaran;
        $bulanList = $selectedTahunAjaran->getBulanSppList();
        $tahunAwal = (int) substr($selectedTahunAjaran->tahun, 0, 4);
        $activeTahunAjaran = TahunAjaran::aktif()->first();
        $activeTahunAjaranId = $activeTahunAjaran ? $activeTahunAjaran->id : 0;

        $writer = SimpleExcelWriter::streamDownload('rekap_pembayaran_' . date('YmdHis') . '.xlsx')
            ->noHeaderRow();

        // Siapkan Style untuk Header Laporan
        $titleStyle = (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(14);
        $subtitleStyle = (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(12);
        $headerTableStyle = (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setBackgroundColor('F3F4F6');

        // Hitung total kolom untuk menempatkan judul di tengah (estimasi)
        $totalCols = ($jenisPembayaran === 'SPP') ? 18 : (($jenisPembayaran === 'DPP') ? 9 : 20);
        $centerColIndex = max(2, (int) floor($totalCols / 2) - 2);
        $rightColIndex = $totalCols - 2;

        // Siapkan Style per kolom untuk Baris 1
        $judulExcel = 'Daftar Pembayaran SPP';
        if ($jenisPembayaran === 'DPP') {
            $judulExcel = 'Daftar Pembayaran DPP';
        } elseif ($jenisPembayaran !== 'SPP') {
            $judulExcel = 'Daftar Pembayaran SPP & DPP';
        }

        $values1 = array_fill(0, $totalCols, '');
        $values1[0] = 'YPKK KERTAS LECES';
        $values1[$centerColIndex] = $judulExcel;
        $values1[$rightColIndex] = 'Tanggal Cetak: ' . date('d-m-Y H:i');

        $styles1 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(14),
            $rightColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
        ];
        
        $row1 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values1, null, $styles1);
        $writer->addRow($row1);

        // Siapkan Style per kolom untuk Baris 2
        $values2 = array_fill(0, $totalCols, '');
        $values2[0] = 'LECES PROBOLINGGO';
        $values2[$centerColIndex] = 'Tahun Ajaran: ' . $selectedTahunAjaran->tahun;

        $styles2 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(12),
        ];

        $row2 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values2, null, $styles2);
        $writer->addRow($row2);

        // Baris 3 (kosong)
        $writer->addRow(array_fill(0, $totalCols, ''));

        // Baris 4 (Header Tabel)
        $headerTable = ['No', 'NIS', 'Nama Siswa', 'Kelas'];
        if ($jenisPembayaran === 'SPP') {
            foreach ($bulanList as $b) {
                $headerTable[] = substr(TahunAjaran::namaBulan($b), 0, 3);
            }
            $headerTable[] = 'Belum Bayar';
            $headerTable[] = 'Total Terbayar';
        } elseif ($jenisPembayaran === 'DPP') {
            $headerTable = array_merge($headerTable, ['Tarif DPP', 'Tarif Lama', 'Terbayar', 'Sisa Tagihan', 'Status']);
        } else {
            foreach ($bulanList as $b) {
                $headerTable[] = substr(TahunAjaran::namaBulan($b), 0, 3);
            }
            $headerTable = array_merge($headerTable, ['Total SPP', 'Total DPP', 'Belum Bayar', 'Status DPP']);
        }
        $writer->addRow($headerTable, $headerTableStyle);

        // Tracking Grand Totals
        $grandTotalBulanBelumBayar = 0;
        $grandTotalSppTerbayar = 0;
        
        $grandTotalDppTarif = 0;
        $grandTotalDppTarifLama = 0;
        $grandTotalDppTerbayar = 0;
        $grandTotalDppSisa = 0;

        foreach ($siswaKelasList as $index => $sk) {
            $siswa = $sk->siswa;
            $kelas = $sk->kelas;
            
            $row = [
                $index + 1,
                $siswa->nis ?? '-',
                $siswa->nama_lengkap ?? '-',
                $kelas->nama_kelas ?? '-',
            ];

            $studentTagihans = $rekapTagihans->get($sk->siswa_id, collect());

            if ($jenisPembayaran === 'SPP') {
                $totalSPPTerbayar = 0;
                $totalBulanBelumBayar = 0;
                foreach ($bulanList as $bulan) {
                    $tahunTagihan = ($bulan < $selectedTahunAjaran->bulan_mulai_spp) ? $tahunAwal + 1 : $tahunAwal;
                    
                    $isBelumBerjalan = false;
                    if ($selectedTahunAjaran->status === 'aktif') {
                        $akhirBulanTagihan = \Carbon\Carbon::create($tahunTagihan, $bulan, 1)->endOfMonth()->startOfDay();
                        $isBelumBerjalan = $akhirBulanTagihan->isFuture();
                    } elseif ($selectedTahunAjaran->id > $activeTahunAjaranId) {
                        $isBelumBerjalan = true;
                    }

                    $tagihan = $studentTagihans->where('tarifPembayaran.jenis', 'SPP')->firstWhere('bulan', $bulan);

                    if ($tagihan) {
                        if ($tagihan->status === 'lunas') {
                            $statusText = '✓';
                            $totalSPPTerbayar += $tagihan->jumlah_terbayar;
                        } elseif ($tagihan->is_tunggakan) {
                            $statusText = '•';
                            $totalSPPTerbayar += $tagihan->jumlah_terbayar;
                            $totalBulanBelumBayar++;
                        } else {
                            $statusText = '-';
                        }
                    } else {
                        $statusText = $isBelumBerjalan ? '-' : '•';
                        if (!$isBelumBerjalan) {
                            $totalBulanBelumBayar++;
                        }
                    }

                    $row[] = $statusText;
                }
                $row[] = $totalBulanBelumBayar > 0 ? $totalBulanBelumBayar : '-';
                $row[] = $totalSPPTerbayar;
                
                $grandTotalBulanBelumBayar += $totalBulanBelumBayar;
                $grandTotalSppTerbayar += $totalSPPTerbayar;

            } elseif ($jenisPembayaran === 'DPP') {
                $dppTagihan = $studentTagihans->where('tarifPembayaran.jenis', 'DPP')->first();
                $tarifDpp = $dppTagihan ? $dppTagihan->jumlah_tagihan : 0;
                $tarifLama = $dppTagihan ? ($dppTagihan->tarif_lama ?? 0) : 0;
                $terbayar = $dppTagihan ? $dppTagihan->jumlah_terbayar : 0;
                $sisa = $dppTagihan ? $dppTagihan->sisa_tagihan : 0;
                
                $row[] = $tarifDpp;
                $row[] = $tarifLama;
                $row[] = $terbayar;
                $row[] = $sisa;
                $row[] = $dppTagihan ? ($dppTagihan->status === 'lunas' ? 'Lunas' : 'Belum Lunas') : '-';
                
                $grandTotalDppTarif += $tarifDpp;
                $grandTotalDppTarifLama += $tarifLama;
                $grandTotalDppTerbayar += $terbayar;
                $grandTotalDppSisa += $sisa;

            } else {
                // Semua
                $totalBulanBelumBayar = 0;
                foreach ($bulanList as $bulan) {
                    $tahunTagihan = ($bulan < $selectedTahunAjaran->bulan_mulai_spp) ? $tahunAwal + 1 : $tahunAwal;
                    
                    $isBelumBerjalan = false;
                    if ($selectedTahunAjaran->status === 'aktif') {
                        $akhirBulanTagihan = \Carbon\Carbon::create($tahunTagihan, $bulan, 1)->endOfMonth()->startOfDay();
                        $isBelumBerjalan = $akhirBulanTagihan->isFuture();
                    } elseif ($selectedTahunAjaran->id > $activeTahunAjaranId) {
                        $isBelumBerjalan = true;
                    }

                    $tagihan = $studentTagihans->where('tarifPembayaran.jenis', 'SPP')->firstWhere('bulan', $bulan);

                    $statusText = '';
                    if ($tagihan) {
                        if ($tagihan->status === 'lunas') {
                            $statusText = '✓';
                        } elseif ($tagihan->is_tunggakan) {
                            $statusText = '•';
                            $totalBulanBelumBayar++;
                        } else {
                            $statusText = '-';
                        }
                    } else {
                        $statusText = $isBelumBerjalan ? '-' : '•';
                        if (!$isBelumBerjalan) {
                            $totalBulanBelumBayar++;
                        }
                    }

                    $row[] = $statusText;
                }

                // Tampilkan DPP
                $dppTagihan = $studentTagihans->where('tarifPembayaran.jenis', 'DPP')->first();
                
                $sppTerbayar = $studentTagihans->where('tarifPembayaran.jenis', 'SPP')->sum('jumlah_terbayar');
                $dppTerbayar = $dppTagihan ? $dppTagihan->jumlah_terbayar : 0;
                
                $row[] = $sppTerbayar;
                $row[] = $dppTerbayar;
                $row[] = $totalBulanBelumBayar > 0 ? $totalBulanBelumBayar : '-';
                $row[] = $dppTagihan ? ($dppTagihan->status === 'lunas' ? 'Lunas' : 'Belum Lunas') : '-';
                
                $grandTotalSppTerbayar += $sppTerbayar;
                $grandTotalDppTerbayar += $dppTerbayar;
                $grandTotalBulanBelumBayar += $totalBulanBelumBayar;
            }

            $writer->addRow($row);
        }

        // --- FOOTER ROW ---
        $footerRow = array_fill(0, count($headerTable), '');
        $footerRow[3] = 'TOTAL KESELURUHAN';
        
        if ($jenisPembayaran === 'SPP') {
            $footerRow[count($headerTable) - 2] = $grandTotalBulanBelumBayar;
            $footerRow[count($headerTable) - 1] = $grandTotalSppTerbayar;
        } elseif ($jenisPembayaran === 'DPP') {
            $footerRow[4] = $grandTotalDppTarif;
            $footerRow[5] = $grandTotalDppTarifLama;
            $footerRow[6] = $grandTotalDppTerbayar;
            $footerRow[7] = $grandTotalDppSisa;
        } else {
            $footerRow[count($headerTable) - 4] = $grandTotalSppTerbayar;
            $footerRow[count($headerTable) - 3] = $grandTotalDppTerbayar;
            $footerRow[count($headerTable) - 2] = $grandTotalBulanBelumBayar;
        }
        $writer->addRow($footerRow, $headerTableStyle);

        return $writer->toBrowser();
    }

    public function exportTagihan(Request $request)
    {
        $tahunAjaranId = $request->tahun_ajaran_id ?: (TahunAjaran::aktif()->first()?->id ?? TahunAjaran::orderBy('tahun', 'desc')->first()?->id);
        $selectedTahunAjaran = TahunAjaran::find($tahunAjaranId);

        if (!$selectedTahunAjaran) {
            return back()->with('error', 'Tahun ajaran tidak valid.');
        }

        $siswaKelasQuery = \App\Models\SiswaKelas::withoutGlobalScope('active')
            ->with(['siswa', 'kelas'])
            ->where('siswa_kelas.tahun_ajaran_id', $tahunAjaranId)
            ->whereHas('siswa', function ($q) {
               $q->where('siswa.status', 'aktif');
            })
            ->join('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id')
            ->orderBy('kelas.jenjang')
            ->orderBy('kelas.tingkat')
            ->orderBy('kelas.paralel')
            ->select('siswa_kelas.*');

        if (auth()->user()->hasRole('wali_kelas')) {
            $siswaKelasQuery->where('kelas_id', auth()->user()->kelas_id);
        } elseif (auth()->user()->hasRole('kepala_sekolah')) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', auth()->user()->jenjang));
        } elseif ($request->jenjang) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', $request->jenjang));
        }

        if ($request->tingkat) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('tingkat', $request->tingkat));
        }
        if ($request->paralel) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('paralel', $request->paralel));
        }
        if ($request->nis) {
            $siswaKelasQuery->whereHas('siswa', fn($q) => $q->where('nis', $request->nis));
        }

        $siswaKelasList = $siswaKelasQuery->get();
        $siswaIds = $siswaKelasList->pluck('siswa_id')->toArray();
        
        $rekapTagihansQuery = Tagihan::with('tarifPembayaran')
            ->whereIn('siswa_id', $siswaIds)
            ->where(function ($q) use ($tahunAjaranId) {
                $q->where('tahun_ajaran_id', $tahunAjaranId)
                  ->orWhere(function ($q2) use ($tahunAjaranId) {
                      $q2->whereHas('tarifPembayaran', fn($t) => $t->where('jenis', 'DPP'))
                         ->where('tahun_ajaran_id', '!=', $tahunAjaranId)
                         ->where('status', '!=', 'lunas');
                  });
            })
            ->get();

        $rekapTagihans = $rekapTagihansQuery->filter(function($t) use ($siswaKelasList, $tahunAjaranId) {
            if ($t->tahun_ajaran_id == $tahunAjaranId) return true;
            $sk = $siswaKelasList->firstWhere('siswa_id', $t->siswa_id);
            $jenjang = $sk && $sk->kelas ? $sk->kelas->jenjang : null;
            return $t->tarifPembayaran && $t->tarifPembayaran->jenjang === $jenjang;
        })->groupBy('siswa_id');

        $writer = SimpleExcelWriter::streamDownload('laporan_tagihan_aktif_' . date('YmdHis') . '.xlsx')
            ->noHeaderRow();
            
        // --- CUSTOM HEADER LAPORAN ---
        $headerTableStyle = (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setBackgroundColor('F3F4F6');
        $totalCols = 7;
        $centerColIndex = 3;
        $rightColIndex = 6;

        // Baris 1
        $values1 = array_fill(0, $totalCols, '');
        $values1[0] = 'YPKK KERTAS LECES';
        $values1[$centerColIndex] = 'Laporan Tagihan';
        $values1[$rightColIndex] = 'Tanggal Cetak: ' . date('d-m-Y H:i');

        $styles1 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(14),
            $rightColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
        ];
        
        $row1 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values1, null, $styles1);
        $writer->addRow($row1);

        // Baris 2
        $values2 = array_fill(0, $totalCols, '');
        $values2[0] = 'LECES PROBOLINGGO';
        $values2[$centerColIndex] = 'Tahun Ajaran: ' . $selectedTahunAjaran->tahun;

        $styles2 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(12),
        ];

        $row2 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values2, null, $styles2);
        $writer->addRow($row2);

        // Baris 3 (kosong)
        $writer->addRow(array_fill(0, $totalCols, ''));

        // Baris 4 (Header Tabel)
        $headerTable = ['No', 'NIS', 'Nama Siswa', 'Kelas', 'Sisa SPP', 'Sisa DPP', 'Total Sisa'];
        $writer->addRow($headerTable, $headerTableStyle);
        // -----------------------------
        
        $no = 1;
        $grandTotalSPP = 0;
        $grandTotalDPP = 0;
        foreach ($siswaKelasList as $sk) {
            $siswa = $sk->siswa;
            $studentTagihans = $rekapTagihans->get($sk->siswa_id, collect());
            
            $tagihanSpp = $studentTagihans->where('tarifPembayaran.jenis', 'SPP')->where('status', '!=', 'lunas')->sum('sisa_tagihan');
            $tagihanDpp = $studentTagihans->where('tarifPembayaran.jenis', 'DPP')->where('status', '!=', 'lunas')->sum('sisa_tagihan');
            $jumlah = $tagihanSpp + $tagihanDpp;

            $grandTotalSPP += $tagihanSpp;
            $grandTotalDPP += $tagihanDpp;

            $writer->addRow([
                $no++,
                $siswa->nis ?? '-',
                $siswa->nama_lengkap ?? '-',
                $sk->kelas->nama_kelas ?? '-',
                $tagihanSpp,
                $tagihanDpp,
                $jumlah,
            ]);
        }

        // Total footer row — sesuai tampilan di aplikasi
        $footerRow = [
            '',
            '',
            '',
            'TOTAL SISA TAGIHAN',
            $grandTotalSPP,
            $grandTotalDPP,
            $grandTotalSPP + $grandTotalDPP,
        ];
        $writer->addRow($footerRow, $headerTableStyle);

        return $writer->toBrowser();
    }

    
    public function exportHarian(Request $request)
    {
        if (auth()->user()->hasAnyRole(['wali_kelas', 'kepala_sekolah'])) {
            abort(403, 'Akses tidak diizinkan untuk melihat laporan harian.');
        }

        $tanggalHarian = $request->tanggal ?? now()->format('Y-m-d');
        // Determine tahun ajaran for filtering
        $tahunAjaranId = $request->tahun_ajaran_id ?: (\App\Models\TahunAjaran::aktif()->first()?->id ?? \App\Models\TahunAjaran::orderBy('tahun', 'desc')->first()?->id);
        $selectedTahunAjaran = \App\Models\TahunAjaran::find($tahunAjaranId);
        $filterTahunAjaranId = $request->tahun_ajaran_id ?? ($selectedTahunAjaran->id ?? null);

        // Build base query
        $queryHarian = \App\Models\TransaksiPembayaran::with(['siswa','user','detailPembayaran.tagihan'])
            ->whereDate('tanggal_bayar', $tanggalHarian);
        if ($filterTahunAjaranId) {
            $queryHarian->where('tahun_ajaran_id', $filterTahunAjaranId);
        }

        // Apply payment method filter if provided
        if ($request->metode_pembayaran) {
            $queryHarian->where('metode_pembayaran', $request->metode_pembayaran);
        }

        // Role based restrictions
        $isWaliKelas = auth()->user() && auth()->user()->hasRole('wali_kelas');
        $kepalaSekolahJenjang = auth()->user() && auth()->user()->hasRole('kepala_sekolah') ? auth()->user()->jenjang : null;
        if ($isWaliKelas) {
            $myKelasId = auth()->user()->kelas_id;
            $queryHarian->whereHas('siswa.siswaKelas', fn($q) => $q->where('kelas_id', $myKelasId));
        } elseif ($kepalaSekolahJenjang) {
            $queryHarian->whereHas('siswa.siswaKelas.kelas', fn($q) => $q->where('jenjang', $kepalaSekolahJenjang));
        }

        $transaksis = $queryHarian->get();

        // Group by Jenjang
        $groupedByJenjang = $transaksis->groupBy(function($item) {

    $kelas = strtoupper($item->nama_kelas_snapshot ?? '');

    if (str_contains($kelas, 'TK')) {
        return 'TK';
    }

    if (str_contains($kelas, 'SD')) {
        return 'SD';
    }

    if (str_contains($kelas, 'SMP')) {
        return 'SMP';
    }

    if (str_contains($kelas, 'SMA')) {
        return 'SMA';
    }

    return 'Lainnya';
});
        $orderJenjang = ['TK' => 1, 'SD' => 2, 'SMP' => 3, 'SMA' => 4];
        $groupedByJenjang = $groupedByJenjang->sortBy(function($items, $key) use ($orderJenjang) {
            return $orderJenjang[$key] ?? 99;
        });

        $writer = SimpleExcelWriter::streamDownload('laporan_penerimaan_harian_' . $tanggalHarian . '.xlsx')
            ->noHeaderRow();

        // --- CUSTOM HEADER LAPORAN ---
        $headerTableStyle = (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setBackgroundColor('F3F4F6');
        $totalCols = 8;
        $centerColIndex = 3;
        $rightColIndex = 7;

        // Baris 1
        $values1 = array_fill(0, $totalCols, '');
        $values1[0] = 'YPKK KERTAS LECES';
        $values1[$centerColIndex] = 'Penerimaan Pembayaran Harian';
        $values1[$rightColIndex] = 'Tanggal Cetak: ' . date('d-m-Y H:i');

        $styles1 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(14),
            $rightColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
        ];
        
        $row1 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values1, null, $styles1);
        $writer->addRow($row1);

        // Baris 2
        $values2 = array_fill(0, $totalCols, '');
        $values2[0] = 'LECES PROBOLINGGO';
        $values2[$centerColIndex] = 'Tanggal: ' . \Carbon\Carbon::parse($tanggalHarian)->translatedFormat('d F Y');

        $styles2 = [
            0 => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(11),
            $centerColIndex => (new \OpenSpout\Common\Entity\Style\Style())->setFontBold()->setFontSize(12),
        ];

        $row2 = \OpenSpout\Common\Entity\Row::fromValuesWithStyles($values2, null, $styles2);
        $writer->addRow($row2);

        // Baris 3 (kosong)
        $writer->addRow(array_fill(0, $totalCols, ''));

        // Baris 4 (Header Tabel)
        $headerTable = ['No', 'NIS', 'Nama Siswa', 'Kelas', 'Bulan Bayar', 'SPP', 'DPP', 'Jumlah'];
        $writer->addRow($headerTable, $headerTableStyle);
        // -----------------------------

        $no = 1;
        $grandTotalSPP = 0;
        $grandTotalDPP = 0;
        $grandTotal = 0;
        foreach ($groupedByJenjang as $jenjang => $transaksis) {
            foreach ($transaksis as $transaksi) {
                $rowSPP = 0;
                $rowDPP = 0;
                $bulanBayar = [];
                foreach ($transaksi->detailPembayaran as $detail) {
                    $jenis = $detail->tagihan->tarifPembayaran->jenis ?? '';
                    if ($jenis === 'SPP') {
                        $rowSPP += $detail->jumlah_bayar;
                        if ($detail->tagihan->nama_bulan) {
                            $bulanBayar[] = substr($detail->tagihan->nama_bulan, 0, 3);
                        }
                    } elseif ($jenis === 'DPP') {
                        $rowDPP += $detail->jumlah_bayar;
                    }
                }

                $grandTotalSPP += $rowSPP;
                $grandTotalDPP += $rowDPP;
                $grandTotal += $transaksi->total_bayar;

                $writer->addRow([
                    $no++,
                    $transaksi->siswa->nis ?? '-',
                    $transaksi->siswa->nama_lengkap ?? '-',
                    $transaksi->nama_kelas_snapshot ?? '-',
                    implode(', ', array_unique($bulanBayar)) ?: '-',
                    $rowSPP,
                    $rowDPP,
                    $transaksi->total_bayar,
                ]);
            }
        }

        // Total footer row — sesuai tampilan di aplikasi
        $footerRow = [
            '',
            '',
            '',
            '',
            'TOTAL PENERIMAAN',
            $grandTotalSPP,
            $grandTotalDPP,
            $grandTotal,
        ];
        $writer->addRow($footerRow, $headerTableStyle);

        return $writer->toBrowser();
    }

    public function exportRiwayat(Request $request)
    {
        $tahunAjaranId = $request->tahun_ajaran_id ?: (\App\Models\TahunAjaran::aktif()->first()?->id ?? \App\Models\TahunAjaran::orderBy('tahun', 'desc')->first()?->id);
        $selectedTahunAjaran = \App\Models\TahunAjaran::find($tahunAjaranId);

        if (!$selectedTahunAjaran) {
            return back()->with('error', 'Tahun ajaran tidak valid.');
        }

        $siswaKelasQuery = \App\Models\SiswaKelas::withoutGlobalScope('active')
            ->with(['siswa', 'kelas'])
            ->where('siswa_kelas.tahun_ajaran_id', $tahunAjaranId)
            ->whereHas('siswa', fn($q) => $q->where('siswa.status', 'aktif'))
            ->join('kelas', 'siswa_kelas.kelas_id', '=', 'kelas.id')
            ->orderBy('kelas.jenjang')
            ->orderBy('kelas.tingkat')
            ->orderBy('kelas.paralel')
            ->select('siswa_kelas.*');

        if (auth()->user()->hasRole('wali_kelas')) {
            $siswaKelasQuery->where('siswa_kelas.kelas_id', auth()->user()->kelas_id);
        } elseif (auth()->user()->hasRole('kepala_sekolah')) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', auth()->user()->jenjang));
        } elseif ($request->jenjang) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('jenjang', $request->jenjang));
        }

        if ($request->tingkat) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('tingkat', $request->tingkat));
        }
        if ($request->paralel) {
            $siswaKelasQuery->whereHas('kelas', fn($q) => $q->where('paralel', $request->paralel));
        }
        if ($request->nis) {
            $siswaKelasQuery->whereHas('siswa', fn($q) => $q->where('nis', $request->nis));
        }

        $siswaKelasList = $siswaKelasQuery->get();
        $siswaIds = $siswaKelasList->pluck('siswa_id')->toArray();

        $transaksis = TransaksiPembayaran::with(['detailPembayaran.tagihan.tarifPembayaran', 'user'])
            ->whereIn('siswa_id', $siswaIds)
            ->where('tahun_ajaran_id', $tahunAjaranId)
            ->orderBy('tanggal_bayar', 'asc')
            ->orderBy('created_at', 'asc')
            ->get()
            ->groupBy('siswa_id');

        $writer = SimpleExcelWriter::streamDownload('laporan_riwayat_pembayaran_' . date('YmdHis') . '.xlsx');

        $no = 1;
        $grandTotal = 0;
        foreach ($siswaKelasList as $sk) {
            $siswa = $sk->siswa;
            $siswaTransaksis = $transaksis->get($sk->siswa_id, collect());
            $totalBayar = $siswaTransaksis->sum('total_bayar');
            $grandTotal += $totalBayar;

            $writer->addRow([
                'No'            => $no++,
                'NIS'           => $siswa->nis ?? '-',
                'Nama Siswa'    => $siswa->nama_lengkap ?? '-',
                'Kelas'         => $sk->kelas->nama_kelas ?? '-',
                'Total Bayar'   => $totalBayar,
            ]);
        }

        $writer->addRow([
            'No'            => '',
            'NIS'           => '',
            'Nama Siswa'    => '',
            'Kelas'         => 'TOTAL KESELURUHAN',
            'Total Bayar'   => $grandTotal,
        ]);

        return $writer->toBrowser();
    }

    public function cetakRiwayat(Request $request)
    {
        $siswa_id = $request->siswa_id;
        $tahunAjaranId = $request->tahun_ajaran_id ?: (\App\Models\TahunAjaran::aktif()->first()?->id);
        $selectedTahunAjaran = \App\Models\TahunAjaran::find($tahunAjaranId);

        $siswa = \App\Models\Siswa::findOrFail($siswa_id);
        $siswaKelas = \App\Models\SiswaKelas::withoutGlobalScope('active')
            ->where('siswa_id', $siswa_id)
            ->where('tahun_ajaran_id', $tahunAjaranId)
            ->first();

        $siswaTransaksis = \App\Models\TransaksiPembayaran::with(['detailPembayaran.tagihan.tarifPembayaran', 'user'])
            ->where('siswa_id', $siswa_id)
            ->where('tahun_ajaran_id', $tahunAjaranId)
            ->orderBy('tanggal_bayar', 'asc')
            ->orderBy('created_at', 'asc')
            ->get();

        return view('laporan.cetak-riwayat', compact('siswa', 'siswaKelas', 'siswaTransaksis', 'selectedTahunAjaran'));
    }

    /**
     * AJAX POST: Kirim Rekap Pembayaran via Fonnte
     */
    public function kirimWaRekap(Request $request)
    {
        $request->validate([
            'siswa_id' => 'required|exists:siswa,id',
            'pesan'    => 'required|string',
        ]);

        $siswa = Siswa::findOrFail($request->siswa_id);
        if (!$siswa->no_wa) {
            return response()->json(['success' => false, 'message' => 'Nomor WA siswa tidak tersedia.'], 422);
        }

        $noWa   = \App\Services\FonnteService::formatNomor($siswa->no_wa);
        $result = app(\App\Services\FonnteService::class)->send($noWa, $request->pesan);

        \App\Models\RiwayatPengirimanWa::create([
            'siswa_id'     => $siswa->id,
            'nama_siswa'   => $siswa->nama_lengkap,
            'no_wa'        => $noWa,
            'jenis_pesan'  => 'Rekap Pembayaran',
            'status'       => $result['success'] ? 'berhasil' : 'gagal',
            'keterangan'   => $result['success'] ? null : ($result['message'] ?? 'Gagal mengirim pesan'),
            'dikirim_oleh' => auth()->id(),
        ]);

        return response()->json($result);
    }

    public function riwayatWa(Request $request)
    {
        $query = \App\Models\RiwayatPengirimanWa::with(['siswa', 'dikirimOleh'])->orderBy('created_at', 'desc');

        if ($request->search) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('nama_siswa', 'like', "%{$search}%")
                  ->orWhere('no_wa', 'like', "%{$search}%")
                  ->orWhereHas('siswa', function($sq) use ($search) {
                      $sq->where('nama_lengkap', 'like', "%{$search}%")
                         ->orWhere('nis', 'like', "%{$search}%");
                  });
            });
        }

        if ($request->tanggal_mulai && $request->tanggal_sampai) {
            $query->whereBetween('created_at', [$request->tanggal_mulai . ' 00:00:00', $request->tanggal_sampai . ' 23:59:59']);
        } elseif ($request->tanggal_mulai) {
            $query->where('created_at', '>=', $request->tanggal_mulai . ' 00:00:00');
        } elseif ($request->tanggal_sampai) {
            $query->where('created_at', '<=', $request->tanggal_sampai . ' 23:59:59');
        }

        if ($request->status) {
            $query->where('status', $request->status);
        }

        if ($request->jenis_pesan) {
            $query->where('jenis_pesan', $request->jenis_pesan);
        }

        $riwayats = $query->paginate(20)->withQueryString();

        return view('laporan.riwayat-wa', compact('riwayats'));
    }

    public function cetakRiwayatWa(Request $request)
    {
        $query = \App\Models\RiwayatPengirimanWa::with(['siswa', 'dikirimOleh'])->orderBy('created_at', 'desc');

        if ($request->search) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('nama_siswa', 'like', "%{$search}%")
                  ->orWhere('no_wa', 'like', "%{$search}%")
                  ->orWhereHas('siswa', function($sq) use ($search) {
                      $sq->where('nama_lengkap', 'like', "%{$search}%")
                         ->orWhere('nis', 'like', "%{$search}%");
                  });
            });
        }

        if ($request->tanggal_mulai && $request->tanggal_sampai) {
            $query->whereBetween('created_at', [$request->tanggal_mulai . ' 00:00:00', $request->tanggal_sampai . ' 23:59:59']);
        } elseif ($request->tanggal_mulai) {
            $query->where('created_at', '>=', $request->tanggal_mulai . ' 00:00:00');
        } elseif ($request->tanggal_sampai) {
            $query->where('created_at', '<=', $request->tanggal_sampai . ' 23:59:59');
        }

        if ($request->status) {
            $query->where('status', $request->status);
        }

        if ($request->jenis_pesan) {
            $query->where('jenis_pesan', $request->jenis_pesan);
        }

        $riwayats = $query->get();

        return view('laporan.cetak-riwayat-wa', compact('riwayats'));
    }
}
