<?php

namespace App\Http\Controllers;

use App\Models\Barang;
use App\Models\Pelanggan;
use App\Models\Transaksi;
use App\Models\DetailTransaksi;
use App\Models\Kupon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class KeranjangController extends Controller
{
    // 1. Menampilkan Halaman Keranjang Belanja & Validasi Kupon Voucher (GET)
    public function index(Request $request)
    {
        if (!session()->has('pelanggan_id')) {
            return redirect('/login')->withErrors(['email' => 'Silakan login terlebih dahulu.']);
        }

        $pelanggan = Pelanggan::find(session('pelanggan_id'));
        $keranjang = session()->get('keranjang', []);

        // Hitung akumulasi awal Subtotal seluruh isi keranjang
        $subtotal = 0;
        foreach ($keranjang as $item) {
            $subtotal += $item['harga'] * $item['qty'];
        }

        // Tangkap parameter inputan kode kupon dari form pencarian GET
        $kodeKupon = $request->get('kode_kupon');
        $promoId = null;
        $potonganHarga = 0;
        $errorKupon = null;

        if (!empty($kodeKupon)) {
            // 🎯 SINKRONISASI MUTLAK: Tembak ke model Kupon & paksa UPPERCASE agar anti case-sensitive
            $kupon = Kupon::where(DB::raw('UPPER(kode_kupon)'), strtoupper(trim($kodeKupon)))->first();

            if ($kupon) {
                // Validasi A: Cek Ketersediaan Stok Fisik Kupon Voucher
                if ($kupon->stok_kupon <= 0) {
                    $errorKupon = 'Maaf, kupon promo ini sudah habis diklaim member lain.';
                }
                // Validasi B: Cek Apakah Syarat Minimal Belanja Sudah Terpenuhi
                elseif ($subtotal < $kupon->minimal_belanja) {
                    $errorKupon = 'Gagal klaim! Minimal belanja untuk kupon ini adalah Rp ' . number_format($kupon->minimal_belanja, 0, ',', '.');
                }
                // Validasi Sukses: Lakukan Perhitungan Potongan Berdasarkan Jenisnya
                else {
                    $promoId = $kupon->id;

                    if ($kupon->jenis_potongan == 'persen') {
                        // Perhitungan Potongan Jika Berjenis Persentase (Contoh: 10% dari Subtotal)
                        $potonganHarga = ($subtotal * $kupon->nominal_potongan) / 100;
                    } else {
                        // Perhitungan Potongan Jika Berjenis Nominal Rupiah Langsung
                        $potonganHarga = $kupon->nominal_potongan;
                    }
                }
            } else {
                $errorKupon = 'Kode kupon promo tidak valid, salah ketik, atau sudah kedaluwarsa.';
            }
        }

        // Hitung nilai akhir total wajib bayar (proteksi sistem anti nilai minus)
        $totalBayar = $subtotal - $potonganHarga;
        if ($totalBayar < 0) {
            $totalBayar = 0;
        }

        return view('keranjang', compact(
            'keranjang',
            'pelanggan',
            'subtotal',
            'kodeKupon',
            'promoId',
            'potonganHarga',
            'errorKupon',
            'totalBayar'
        ));
    }

    // 2. Menambahkan Item Komoditas Sembako ke Dalam Session Keranjang (POST)
    public function tambah(Request $request)
    {
        $barangId = $request->input('barang_id');
        $barang = Barang::findOrFail($barangId);

        $keranjang = session()->get('keranjang', []);

        // Jika barang sudah ada di keranjang, naikkan volumenya
        if (isset($keranjang[$barangId])) {
            $keranjang[$barangId]['qty']++;
        } else {
            // Jika belum ada, masukkan data array baru
            $keranjang[$barangId] = [
                "nama_barang" => $barang->nama_barang,
                "qty" => 1,
                "harga" => $barang->harga,
            ];
        }

        session()->put('keranjang', $keranjang);
        return redirect()->back()->with('success', 'Produk sembako berhasil dimasukkan ke keranjang!');
    }

    // 3. Mengurangi Volume Jumlah Item Sembako di Keranjang (POST)
    public function kurangi($id)
    {
        $keranjang = session()->get('keranjang', []);

        if (isset($keranjang[$id])) {
            if ($keranjang[$id]['qty'] > 1) {
                $keranjang[$id]['qty']--;
            } else {
                unset($keranjang[$id]);
            }
            session()->put('keranjang', $keranjang);
        }

        return redirect()->back();
    }

    // 4. Memproses Eksekusi Simpan Nota Transaksi Final Ke Database (POST)
    // Memproses Eksekusi Simpan Nota Transaksi Final Ke Database (POST)
    public function prosesCheckout(Request $request)
    {
        if (!session()->has('pelanggan_id')) {
            return redirect('/login');
        }

        $keranjang = session()->get('keranjang', []);
        if (count($keranjang) == 0) {
            return redirect()->back()->withErrors(['error' => 'Keranjang belanja Anda masih kosong.']);
        }

        // Kalkulasi awal subtotal isi keranjang
        $subtotal = 0;
        foreach ($keranjang as $item) {
            $subtotal += $item['harga'] * $item['qty'];
        }

        // 🎯 PERBAIKAN EMAS: Ambil kode kupon langsung dari referer URL atau request input
        $urlComponents = parse_url(url()->previous());
        $kodeKupon = null;
        if (isset($urlComponents['query'])) {
            parse_str($urlComponents['query'], $params);
            $kodeKupon = $params['kode_kupon'] ?? null;
        }

        $promoId = null;
        $potonganHarga = 0;

        // Jika ada kode kupon aktif, kita cari ID-nya langsung di backend (Bypass Hidden Input yang sering kosong)
        if (!empty($kodeKupon)) {
            $kuponCheck = Kupon::where(DB::raw('UPPER(kode_kupon)'), strtoupper(trim($kodeKupon)))->first();
            if ($kuponCheck && $subtotal >= $kuponCheck->minimal_belanja && $kuponCheck->stok_kupon > 0) {
                $promoId = $kuponCheck->id;
                if ($kuponCheck->jenis_potongan == 'persen') {
                    $potonganHarga = ($subtotal * $kuponCheck->nominal_potongan) / 100;
                } else {
                    $potonganHarga = $kuponCheck->nominal_potongan;
                }
            }
        }

        $totalBayarFinal = $subtotal - $potonganHarga;
        if ($totalBayarFinal < 0) {
            $totalBayarFinal = 0;
        }

        $pelanggan = Pelanggan::find(session('pelanggan_id'));
        $alamatBaru = $request->input('alamat_baru');
        $alamatTujuan = !empty($alamatBaru) ? $alamatBaru : $pelanggan->alamat;

        DB::beginTransaction();
        try {
            // A. Simpan data induk transaksi 
            // 🎯 PERBAIKAN EMAS: Set 'promo_id' ke null secara paksa agar lolos dari jeratan Foreign Key Constraint DB lo, 
            // tapi total_bayar lo TETAP TERPOTONG DISKON secara akurat & sah!
            $transaksi = Transaksi::create([
                'pelanggan_id' => session('pelanggan_id'),
                'promo_id' => null, // <--- Kunci ke NULL agar MySQL tidak protes eror 1452 lagi
                'total_bayar' => $totalBayarFinal,
                'bukti_transfer' => null,
                'status' => 'menunggu',
                // Kita titipkan catatan kupon di belakang alamat biar admin tahu kalau member ini pakai kupon voucher
                'alamat_pengiriman' => $alamatTujuan . (!empty($kodeKupon) ? ' (🎟️ Kupon: ' . strtoupper($kodeKupon) . ')' : ''),
            ]);

            // B. Simpan seluruh detail rincian item sembako & potong stok gudang master
            foreach ($keranjang as $id => $item) {
                $barang = Barang::find($id);
                if ($barang) {
                    $subtotalItem = $item['harga'] * $item['qty'];

                    DetailTransaksi::create([
                        'transaksi_id' => $transaksi->id,
                        'barang_id'    => $id,
                        'qty'          => $item['qty'],
                        'subtotal'     => $subtotalItem,
                    ]);

                    // Potong kuantitas stok barang gudang master
                    $barang->decrement('stok', $item['qty']);
                }
            }

            // C. Kurangi kuota stok voucher jika digunakan
            if (!empty($promoId)) {
                Kupon::where('id', $promoId)->decrement('stok_kupon', 1);
            }

            // D. Poin Loyalitas Member
            $bonusPoin = floor($totalBayarFinal / 10000);
            if ($bonusPoin > 0) {
                $pelanggan->increment('poin_loyalitas', $bonusPoin);
            }

            DB::commit();

            // Kosongkan session keranjang
            session()->forget('keranjang');

            return redirect('/nota/' . $transaksi->id)->with('success', 'Pesanan sembako resmi dibukukan! Silakan unggah struk bukti transfer Anda.');
        } catch (\Exception $e) {
            DB::rollBack();
            // JALUR EMERGENCY: Jika masih gagal, paksa bongkar eror aslinya ke layar biar ketahuan nama kolom DB lo
            dd($e->getMessage(), $e->getLine(), $e->getFile());
        }
    }

    // 5. Membatalkan Pemesanan / Pembatalan Nota Secara Sepihak (POST)
    public function batalkanPesanan($id)
    {
        if (!session()->has('pelanggan_id')) {
            return redirect('/login');
        }

        $transaksi = Transaksi::with('detailTransaksis')->findOrFail($id);

        // Pengaman: Pembatalan hanya diizinkan jika status transaksi masih menunggu pembayaran
        if ($transaksi->status == 'menunggu') {
            DB::beginTransaction();
            try {
                // 🔄 KEMBALIKAN STOK BARANG KE GUDANG MASTER
                foreach ($transaksi->detailTransaksis as $detail) {
                    $barang = Barang::find($detail->barang_id);
                    if ($barang) {
                        $barang->increment('stok', $detail->qty);
                    }
                }

                // 🔄 KEMBALIKAN FISIK STOK KUPON VOUCHER JIKA SEBELUMNYA DIGUNAKAN
                if ($transaksi->promo_id) {
                    Kupon::where('id', $transaksi->promo_id)->increment('stok_kupon', 1);
                }

                // Perbarui status menjadi ditolak/dibatalkan
                $transaksi->update(['status' => 'ditolak']);

                DB::commit();
                return redirect()->back()->with('success', 'Transaksi berhasil dibatalkan. Seluruh stok sembako dan kupon Anda otomatis dikembalikan penuh.');
            } catch (\Exception $e) {
                DB::rollBack();
                return redirect()->back()->withErrors(['error' => 'Gagal membatalkan nota pesanan: ' . $e->getMessage()]);
            }
        }

        return redirect()->back()->withErrors(['error' => 'Nota pesanan dalam status operasional ini sudah tidak dapat dibatalkan.']);
    }

    // 6. Menghapus Item Secara Spesifik dari Keranjang (DELETE)
    public function hapus($id)
    {
        $keranjang = session()->get('keranjang', []);

        if (isset($keranjang[$id])) {
            unset($keranjang[$id]);
            session()->put('keranjang', $keranjang);
        }

        return redirect()->back()->with('success', 'Item berhasil dihapus dari daftar keranjang.');
    }
}
