<?php
namespace App\Http\Controllers;

use App\Models\Siswa;
use App\Models\Tagihan;
use App\Models\TransaksiPembayaran;
use App\Models\DetailPembayaran;
use App\Models\TahunAjaran;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

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

    public function create(Request $request)
    {
        $siswa = null;
        $tagihanSPP = collect();
        $tagihanDPP = collect();
        $riwayatTerbaru = collect();


        $selectedTahunAjaranId = null;
        $tahunAjaranList = collect();

        if ($request->filled('nis')) {
            $siswa = Siswa::where('nis', $request->nis)->first();
            if ($siswa) {
                // Generate tagihan for the active month (if needed)
                app(\App\Services\TagihanService::class)->autoGenerateActiveMonth();

                $tahunAjaranList = TahunAjaran::whereHas('tagihan', function($q) use ($siswa) {
                    $q->where('siswa_id', $siswa->id);
                })->orderBy('tahun', 'desc')->get();

                $selectedTahunAjaranId = $request->query('tahun_ajaran_id');
                if (!$selectedTahunAjaranId) {
                    $activeTA = TahunAjaran::aktif()->first();
                    if ($activeTA && $siswa->siswaKelasHistory()->where('tahun_ajaran_id', $activeTA->id)->exists()) {
                        $selectedTahunAjaranId = $activeTA->id;
                    } else {
                        $latestSK = $siswa->siswaKelasHistory()->orderByDesc('id')->first();
                        if ($latestSK) {
                            $selectedTahunAjaranId = $latestSK->tahun_ajaran_id;
                        } else {
                            $latestTagihan = Tagihan::where('siswa_id', $siswa->id)->orderByDesc('created_at')->first();
                            if ($latestTagihan) {
                                $selectedTahunAjaranId = $latestTagihan->tahun_ajaran_id;
                            } elseif ($tahunAjaranList->isNotEmpty()) {
                                $selectedTahunAjaranId = $tahunAjaranList->first()->id;
                            } else {
                                $selectedTahunAjaranId = TahunAjaran::aktif()->first()->id ?? null;
                            }
                        }
                    }
                }

                $siswaKelasInSelectedYear = $siswa->siswaKelasHistory()->where('tahun_ajaran_id', $selectedTahunAjaranId)->first();
                $jenjangInSelectedYear = $siswaKelasInSelectedYear?->kelas?->jenjang;

                $semuaTagihan = Tagihan::with(['kelas', 'tahunAjaran', 'tarifPembayaran'])
                    ->where('siswa_id', $siswa->id)
                    ->whereIn('status', ['belum_bayar', 'kurang'])
                    ->get();

                // Ensure DPP tagihan have the correct tarif based on student's jenjang and tahun ajaran
                $semuaTagihan->each(function ($tagihan) use ($siswa) {
                    if ($tagihan->tarifPembayaran) {
                        return;
                    }
                    $skForTagihan = $siswa->siswaKelasHistory()->where('tahun_ajaran_id', $tagihan->tahun_ajaran_id)->first();
                    $jenjang = $skForTagihan?->kelas?->jenjang;
                    $tarif = \App\Models\TarifPembayaran::where('jenis', 'DPP')
                        ->where('jenjang', $jenjang)
                        ->where('tahun_ajaran_id', $tagihan->tahun_ajaran_id)
                        ->first();
                    if ($tarif) {
                        $tagihan->jumlah_tagihan = $tarif->nominal;
                    }
                });
                $semuaTagihan = $semuaTagihan->filter(fn($t) => $t->tarifPembayaran !== null);

                // Filter SPP
                $tagihanSPP = $semuaTagihan->filter(function($t) use ($selectedTahunAjaranId) {
                    if ($t->tarifPembayaran && $t->tarifPembayaran->jenis === 'SPP') {
                        return !$selectedTahunAjaranId || $t->tahun_ajaran_id == $selectedTahunAjaranId;
                    }
                    return false;
                })->sortBy(function($t) {
                    return $t->tahun . str_pad($t->bulan, 2, '0', STR_PAD_LEFT);
                })->values();

                // Filter DPP
                $tagihanDPP = $semuaTagihan->filter(function($t) use ($selectedTahunAjaranId, $jenjangInSelectedYear) {
                    if (!$t->tarifPembayaran || $t->tarifPembayaran->jenis !== 'DPP') {
                        return false;
                    }

                    // 1. If the DPP belongs to the selected school year
                    if ($t->tahun_ajaran_id == $selectedTahunAjaranId) {
                        return true;
                    }

                    // 2. If it belongs to a different school year, but is from the SAME jenjang AND is NOT lunas
                    $jenjangTagihan = $t->tarifPembayaran->jenjang;
                    if ($jenjangTagihan && $jenjangInSelectedYear && $jenjangTagihan === $jenjangInSelectedYear) {
                        return $t->status !== 'lunas';
                    }

                    return false;
                })->values();
            }
        } else {
            $riwayatTerbaru = TransaksiPembayaran::with([
                'siswa',
                'user',
                'detailPembayaran.tagihan'
            ])
                ->orderByDesc('created_at')
                ->limit(10)
                ->get();
        }

        if (!$siswa) {
            $tahunAjaranList = TahunAjaran::orderByDesc('id')->get();
        }

        return view('transaksi.create', compact(
            'siswa',
            'tagihanSPP',
            'tagihanDPP',
            'riwayatTerbaru',
            'tahunAjaranList',
            'selectedTahunAjaranId'
        ));
    }

    public function store(Request $request)
    {
        // Validate required fields; we ignore provided jumlah_bayar values since payment amount derives from tagihan
        $request->validate([
            'siswa_id' => 'required|exists:siswa,id',
            'metode_pembayaran' => 'required|in:tunai,transfer,qris',
            'tagihan_ids' => 'required|array|min:1',
            'jumlah_bayar' => 'sometimes|array',
            'bukti_bayar' => 'nullable|image|max:2048',
        ]);

        $siswa = Siswa::findOrFail($request->siswa_id);
        $totalBayar = 0;
        $details = [];

        foreach ($request->tagihan_ids as $tagihanId) {
            $tagihan = Tagihan::with(['tarifPembayaran', 'kelas', 'tahunAjaran'])->findOrFail($tagihanId);

            $isDpp = $tagihan->tarifPembayaran && $tagihan->tarifPembayaran->jenis === 'DPP';
            $bayar = $isDpp ? ($request->jumlah_bayar[$tagihanId] ?? 0) : $tagihan->jumlah_tagihan;
            $bayar = (float) $bayar;

            // Calculate remaining balance
            $sisa = $tagihan->jumlah_tagihan - $tagihan->jumlah_terbayar;
            if ($sisa <= 0) {
                continue; // already fully paid
            }
            if ($bayar <= 0) {
                continue; // no payment amount provided
            }
            if ($bayar > $sisa) {
                $bayar = $sisa;
            }
            $totalBayar += $bayar;
            $details[] = ['tagihan' => $tagihan, 'bayar' => $bayar];
        }

        $tahunAjaranTransaksi = $details[0]['tagihan']->tahun_ajaran_id ?? null;
        $buktiPath = null;
        if ($request->hasFile('bukti_bayar')) {
            $buktiPath = $request->file('bukti_bayar')->store('bukti_pembayaran', 'public');
        }
        
        $transaksi = DB::transaction(function () use ($siswa, $request, $totalBayar, $details, $tahunAjaranTransaksi, $buktiPath) {
            $tagihanPertama = $details[0]['tagihan'];
            $transaksi = TransaksiPembayaran::create([
                'kode_transaksi' => TransaksiPembayaran::generateKodeTransaksi(),
                'siswa_id' => $siswa->id,
                'user_id' => Auth::id(),
                'tahun_ajaran_id' => $tahunAjaranTransaksi,
                'nama_kelas_snapshot' => $tagihanPertama->kelas?->nama_kelas,
                'tahun_ajaran_snapshot' => $tagihanPertama->tahunAjaran?->tahun,
                'tarif_snapshot' => $tagihanPertama->tarif_lama ?? null,
                'tanggal_bayar' => now()->toDateString(),
                'total_bayar' => $totalBayar,
                'metode_pembayaran' => $request->metode_pembayaran,
                'keterangan' => $request->keterangan,
                'bukti_bayar' => $buktiPath,
            ]);

            foreach ($details as $detail) {
                $tagihan = $detail['tagihan'];
                DetailPembayaran::create([
                    'transaksi_pembayaran_id' => $transaksi->id,
                    'tagihan_id' => $tagihan->id,
                    'jumlah_bayar' => $detail['bayar'],
                ]);
                // Payment applied via DetailPembayaran observer
            }

            return $transaksi;
        });

        // After successful payment, redirect to the receipt (bukti) page for this transaction.
        return redirect()->route('transaksi.bukti', $transaksi)
            ->with('success', 'Pembayaran berhasil disimpan!');
    }

    public function bukti(TransaksiPembayaran $transaksi)
    {
        $transaksi->load([
            'user',
            'detailPembayaran.tagihan.tarifPembayaran',
            'detailPembayaran.tagihan.kelas',
            'detailPembayaran.tagihan.tahunAjaran',
        ]);
        return view('transaksi.bukti', compact('transaksi'));
    }

    /**
     * AJAX POST: Kirim Bukti Transaksi via Fonnte
     */
    public function kirimWaBukti(Request $request)
    {
        $request->validate([
            'transaksi_id' => 'required|exists:transaksi_pembayaran,id',
        ]);

        $transaksi = TransaksiPembayaran::with([
            'siswa',
            'user',
            'detailPembayaran.tagihan.tarifPembayaran',
        ])->findOrFail($request->transaksi_id);

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

        // Bangun pesan (sama persis dengan yang di bukti.blade.php)
        $text = "*BUKTI PEMBAYARAN SPP*\n";
        $text .= "--------------------------------------\n";
        $text .= "No. Transaksi: {$transaksi->kode_transaksi}\n";
        $text .= "Tanggal: " . Carbon::parse($transaksi->tanggal_bayar)->translatedFormat('d F Y') . " " . $transaksi->created_at->format('H:i') . "\n";
        $text .= "Nama Siswa: {$siswa->nama_lengkap}\n";
        $text .= "Kelas: " . ($transaksi->nama_kelas_snapshot ?? '-') . "\n";
        $text .= "--------------------------------------\n";
        $text .= "Rincian:\n";
        foreach ($transaksi->detailPembayaran as $detail) {
            $tagihan = $detail->tagihan;
            $jenis = $tagihan->tarifPembayaran->jenis ?? '-';
            if ($jenis === 'SPP') {
                $keterangan = 'SPP ' . ($tagihan->nama_bulan ?? '') . ' ' . ($tagihan->tahun ?? '');
            } else {
                $keterangan = 'DPP';
            }
            $text .= "- {$keterangan}: Rp " . number_format($detail->jumlah_bayar, 0, ',', '.') . "\n";
        }
        $text .= "--------------------------------------\n";
        $text .= "*Total Pembayaran: Rp " . number_format($transaksi->total_bayar, 0, ',', '.') . "*\n\n";
        $text .= "Terima kasih atas pembayarannya.";

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

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

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