<?php

namespace App\Http\Controllers;

use App\Models\UserAlamat;
use App\Models\Pesanan;
use App\Models\PesananDetail;
use App\Models\Keranjang;
use App\Models\Produk;
use App\Models\Toko;
use App\Models\KurirAssignment;
use App\Traits\SendsInvoice;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Mail\InvoiceMail;
use App\Helpers\DiskonHelper;

class PesananController extends Controller
{
    use SendsInvoice;

    public function __construct()
    {
        $this->middleware('auth');
    }

    // =========================
    // LIST PESANAN USER
    // =========================
    public function index(Request $request)
    {
        $query = Pesanan::with(['alamat', 'detail.produk', 'kurirAssignment'])
            ->where('user_id', auth()->id())
            ->latest();

        // Server-side filtering by status
        if ($request->has('status') && $request->status != 'all') {
            if ($request->status == 'dibayar') {
                $query->whereIn('status', ['dibayar', 'diproses']);
            } else {
                $query->where('status', $request->status);
            }
        }

        // Server-side searching by kode_pesanan (Smart Search)
        if ($request->filled('search')) {
            $searchTerm = $request->search;

            // Cek apakah ada kecocokan persis (Exact Match)
            $exactMatch = Pesanan::where('user_id', auth()->id())
                ->where('kode_pesanan', $searchTerm)
                ->first();

            if ($exactMatch) {
                // Langsung arahkan ke halaman detail sesuai permintaan (langsung muncul)
                return redirect()->route('pesanan.show', $exactMatch->id)
                    ->with('success', 'Pesanan ditemukan!');
            }

            // Jika tidak persis, lakukan pencarian parsial
            $query->where('kode_pesanan', 'like', '%' . $searchTerm . '%');
        }

        $pesanan = $query->paginate(5);

        // Hitung semua counter secara langsung dari database
        $totalPesanan    = Pesanan::where('user_id', auth()->id())->count();
        $pendingCount    = Pesanan::where('user_id', auth()->id())->where('status', 'pending')->count();
        $dikirimCount    = Pesanan::where('user_id', auth()->id())->where('status', 'dikirim')->count();
        $selesaiCount    = Pesanan::where('user_id', auth()->id())->where('status', 'selesai')->count();
        $dibatalkanCount = Pesanan::where('user_id', auth()->id())->where('status', 'dibatalkan')->count();

        return view('pesanan.index', compact(
            'pesanan',
            'totalPesanan',
            'pendingCount',
            'dikirimCount',
            'selesaiCount',
            'dibatalkanCount'
        ));
    }

    // =========================
    // DETAIL PESANAN
    // =========================
    public function show($id)
    {
        $pesanan = Pesanan::with([
            'user',
            'detail.produk',
            'alamat.province',
            'alamat.city',
            'alamat.district',
            'alamat.village',
            'pembayaran',
            'kurir',
            'kurirAssignment'
        ])
            ->where('user_id', auth()->id())
            ->findOrFail($id);

        $statusDisplay = $pesanan->status;

        $statusIcon = match($statusDisplay) {
            'pending'    => 'fa-hourglass-half',
            'dibayar'    => 'fa-check-circle',
            'diproses'   => 'fa-cog',
            'dikirim'    => 'fa-truck',
            'selesai'    => 'fa-check-double',
            'dibatalkan' => 'fa-times-circle',
            default      => 'fa-receipt',
        };

        $statusLabel = match($statusDisplay) {
            'pending'    => 'Menunggu Pembayaran',
            'dibayar'    => 'Sudah Dibayar',
            'diproses'   => 'Sedang Diproses',
            'dikirim'    => 'Sedang Dikirim',
            'selesai'    => 'Selesai',
            'dibatalkan' => 'Dibatalkan',
            default      => 'Unknown',
        };

        $statusClass = match($statusDisplay) {
            'pending'    => 'bg-yellow-100 text-yellow-800 border-yellow-300',
            'dibayar'    => 'bg-blue-100 text-blue-800 border-blue-300',
            'diproses'   => 'bg-purple-100 text-purple-800 border-purple-300',
            'dikirim'    => 'bg-indigo-100 text-indigo-800 border-indigo-300',
            'selesai'    => 'bg-green-100 text-green-800 border-green-300',
            'dibatalkan' => 'bg-red-100 text-red-800 border-red-300',
            default      => 'bg-gray-100 text-gray-800 border-gray-300',
        };

        $statusText = match($statusDisplay) {
            'pending'    => 'Menunggu pembayaran dari Anda',
            'dibayar'    => 'Pembayaran telah dikonfirmasi',
            'diproses'   => 'Pesanan sedang diproses',
            'dikirim'    => 'Pesanan dalam perjalanan',
            'selesai'    => 'Pesanan telah selesai',
            'dibatalkan' => 'Pesanan dibatalkan',
            default      => '-',
        };

        $additionalLabel = null;

        // Estimasi tiba (hanya untuk status dikirim)
        $estimasiTiba     = null;
        $estimasiLabel    = null;
        $jarakKm          = null;
        $menggunakanJarak = false;

        if ($statusDisplay === 'dikirim' && $pesanan->kurirAssignment) {
            $tglKirim     = \Carbon\Carbon::parse($pesanan->kurirAssignment->created_at);
            $estimasiTiba = $tglKirim->copy()->addDays(3);
            $estimasiLabel = '3 hari';
        }

        return view('pesanan.show', compact(
            'pesanan',
            'statusDisplay',
            'statusIcon',
            'statusLabel',
            'statusClass',
            'statusText',
            'additionalLabel',
            'estimasiTiba',
            'estimasiLabel',
            'jarakKm',
            'menggunakanJarak'
        ));
    }

    // =========================
    // CHECKOUT DARI KERANJANG
    // =========================
    public function store(Request $request)
    {
        $request->validate([
            'items'             => 'required|array',
            'items.*.produk_id' => 'required|exists:produk,id',
            'items.*.jumlah'    => 'required|integer|min:1',
            'items.*.warna'     => 'nullable|string',
            'items.*.ukuran'    => 'nullable|string',
        ]);

        DB::beginTransaction();

        try {
            $alamatUtama = UserAlamat::with('province')
                ->where('user_id', auth()->id())
                ->where('alamat_utama', 1)
                ->first();

            if (!$alamatUtama) {
                return redirect()->route('user-alamat.create')
                    ->with('warning', 'Silakan tambahkan alamat utama terlebih dahulu');
            }

            $items       = $request->items;
            $subtotalSebelumDiskon = 0;
            $detailItems = [];
            $beratTotal  = 0;

            foreach ($items as $item) {
                $produk = Produk::find($item['produk_id']);

                if (!$produk) {
                    throw new \Exception('Produk tidak ditemukan');
                }

                if ($produk->stok < $item['jumlah']) {
                    throw new \Exception("Stok produk {$produk->nama_produk} tidak mencukupi");
                }

                $subtotal    = $produk->harga * $item['jumlah'];
                $subtotalSebelumDiskon += $subtotal;
                $beratTotal += ($produk->berat ?? 0) * $item['jumlah'];

                $detailItems[] = [
                    'produk_id'   => $item['produk_id'],
                    'jumlah'      => $item['jumlah'],
                    'harga'       => $produk->harga,
                    'subtotal'    => $subtotal,
                    'warna'       => $item['warna'] ?? null,
                    'ukuran'      => $item['ukuran'] ?? null,
                    'nama_produk' => $produk->nama_produk,
                    'user_id'     => $produk->user_id,
                ];
            }

            $toko   = \App\Models\Toko::with('province')
                ->where('user_id', $detailItems[0]['user_id'])
                ->first();

            // Hitung diskon otomatis
            $diskonData       = DiskonHelper::hitungDiskonOtomatis($subtotalSebelumDiskon, $toko);
            $diskon           = $diskonData['diskon'];
            $keteranganDiskon = $diskonData['keterangan'];

            // Hitung ongkir
            $ongkir      = 15000;
            $ongkirDetail = 'Koordinat belum tersedia, ongkir default';

            if ($toko && $toko->latitude && $toko->longitude &&
                $alamatUtama->latitude && $alamatUtama->longitude) {

                $result = \App\Helpers\OngkirHelper::hitung(
                    (float) $toko->latitude,
                    (float) $toko->longitude,
                    (float) $alamatUtama->latitude,
                    (float) $alamatUtama->longitude,
                    $toko->province->name ?? '',
                    optional($alamatUtama->province)->name ?? '',
                    (float) $beratTotal
                );

                $ongkir      = $result['ongkir'];
                $ongkirDetail = $result['detail'];

                Log::info('ONGKIR CALCULATION (store)', $result);
            }

            Log::info('ONGKIR CALCULATION', [
                'toko_provinsi' => $toko->province->name ?? null,
                'user_provinsi' => $alamatUtama->province->name ?? null,
                'berat'         => $beratTotal,
                'ongkir'        => $ongkir,
                'detail'        => $ongkirDetail,
            ]);

            $totalSetelahDiskon = $subtotalSebelumDiskon - $diskon;
            $totalBayar         = $totalSetelahDiskon + $ongkir;

            $catatanPesanan = null;
            if ($diskon > 0) {
                $catatanPesanan = json_encode([
                    'diskon'                  => $diskon,
                    'keterangan'              => $keteranganDiskon,
                    'subtotal_sebelum_diskon' => $subtotalSebelumDiskon,
                    'subtotal_setelah_diskon' => $totalSetelahDiskon,
                    'waktu'                   => now()->toDateTimeString(),
                ]);
            }

            $pesanan = Pesanan::create([
                'user_id'      => auth()->id(),
                'alamat_id'    => $alamatUtama->ID,
                'kode_pesanan' => 'PSN-' . strtoupper(Str::random(8)),
                'total_harga'  => $totalBayar,
                'status'       => 'pending',
                'catatan'      => $catatanPesanan,
            ]);

            foreach ($detailItems as $item) {
                PesananDetail::create([
                    'pesanan_id'  => $pesanan->id,
                    'produk_id'   => $item['produk_id'],
                    'nama_produk' => $item['nama_produk'],
                    'harga'       => $item['harga'],
                    'qty'         => $item['jumlah'],
                    'subtotal'    => $item['subtotal'],
                    'warna'       => $item['warna'],
                    'ukuran'      => $item['ukuran'],
                ]);

                $p = Produk::find($item['produk_id']);
                $p->stok -= $item['jumlah'];
                $p->save();

                Keranjang::where('user_id', auth()->id())
                    ->where('produk_id', $item['produk_id'])
                    ->where('warna', $item['warna'])
                    ->where('ukuran', $item['ukuran'])
                    ->delete();
            }

            DB::commit();

            return redirect()->route('pembayaran.create', $pesanan->id)
                ->with('success', 'Pesanan berhasil dibuat! Silakan selesaikan pembayaran.');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'Gagal membuat pesanan: ' . $e->getMessage())
                ->withInput();
        }
    }

    // =========================
    // BUY NOW
    // =========================
    public function buyNow(Request $request)
    {
        $request->validate([
            'produk_id' => 'required|exists:produk,id',
            'qty'       => 'required|integer|min:1',
            'warna'     => 'nullable|string',
            'ukuran'    => 'nullable|string',
        ]);

        session(['buy_now' => $request->only('produk_id', 'qty', 'warna', 'ukuran')]);

        $alamat = UserAlamat::where('user_id', auth()->id())
            ->where('alamat_utama', 1)
            ->first();

        if ($alamat) {
            return redirect()->route('checkout.process', $alamat->ID);
        }

        return redirect()->route('user-alamat.create', ['from' => 'checkout'])
            ->with('warning', 'Silakan tambahkan alamat utama terlebih dahulu');
    }

    // =========================
    // PROSES BUY NOW
    // =========================
    public function processBuyNow($alamatId)
    {
        $data = session('buy_now');

        if (!$data) {
            return redirect()->route('produk.index')
                ->with('error', 'Session buy now tidak ditemukan');
        }

        DB::beginTransaction();

        try {
            $produk = Produk::findOrFail($data['produk_id']);

            if ($produk->stok < $data['qty']) {
                throw new \Exception('Stok tidak mencukupi');
            }

            $subtotalSebelumDiskon = $produk->harga * $data['qty'];

            $alamat = \App\Models\UserAlamat::with('province')
                ->where('ID', $alamatId)
                ->first();

            if (!$alamat) {
                throw new \Exception('Alamat tidak ditemukan');
            }

            $toko = \App\Models\Toko::with('province')
                ->where('user_id', $produk->user_id)
                ->first();

            $diskonData       = DiskonHelper::hitungDiskonOtomatis($subtotalSebelumDiskon, $toko);
            $diskon           = $diskonData['diskon'];
            $keteranganDiskon = $diskonData['keterangan'];

            $beratTotal = (float) (($produk->berat ?? 0) * $data['qty']);

            $result = \App\Helpers\OngkirHelper::hitung(
                $toko->latitude ?? null,
                $toko->longitude ?? null,
                $alamat->latitude ?? null,
                $alamat->longitude ?? null,
                $toko->province->name ?? '',
                optional($alamat->province)->name ?? '',
                $beratTotal
            );

            $ongkir      = $result['ongkir'];
            $ongkirDetail = $result['detail'];

            Log::info('ONGKIR BUYNOW', $result);

            $totalSetelahDiskon = $subtotalSebelumDiskon - $diskon;
            $totalBayar         = $totalSetelahDiskon + $ongkir;

            $catatanPesanan = array_merge([
                'diskon'                  => $diskon,
                'keterangan_diskon'       => $keteranganDiskon,
                'subtotal_sebelum_diskon' => $subtotalSebelumDiskon,
                'subtotal_setelah_diskon' => $totalSetelahDiskon,
                'waktu'                   => now()->toDateTimeString(),
            ], $result);

            $pesanan = Pesanan::create([
                'user_id'      => auth()->id(),
                'alamat_id'    => $alamatId,
                'kode_pesanan' => 'PSN-' . strtoupper(Str::random(8)),
                'total_harga'  => $totalBayar,
                'status'       => 'pending',
                'catatan'      => json_encode($catatanPesanan),
            ]);

            PesananDetail::create([
                'pesanan_id'  => $pesanan->id,
                'produk_id'   => $data['produk_id'],
                'nama_produk' => $produk->nama_produk,
                'harga'       => $produk->harga,
                'qty'         => $data['qty'],
                'subtotal'    => $subtotalSebelumDiskon,
                'warna'       => $data['warna'] ?? null,
                'ukuran'      => $data['ukuran'] ?? null,
            ]);

            $produk->stok -= $data['qty'];
            $produk->save();

            DB::commit();

            session()->forget('buy_now');

            return redirect()->route('pembayaran.create', $pesanan->id)
                ->with('success', 'Pesanan berhasil dibuat! Silakan selesaikan pembayaran.');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                ->with('error', 'Gagal membuat pesanan: ' . $e->getMessage());
        }
    }

    // =========================
    // BATALKAN PESANAN
    // =========================
    public function batal(Request $request, $id)
    {
        $request->validate([
            'catatan' => 'required|string|max:1000',
        ]);

        $pesanan = Pesanan::where('user_id', auth()->id())->findOrFail($id);

        if (!in_array($pesanan->status, ['pending', 'diproses'])) {
            return back()->with('error', 'Pesanan tidak dapat dibatalkan karena statusnya ' . $pesanan->status);
        }

        DB::beginTransaction();

        try {
            // Hapus data pembayaran jika ada agar data tidak menumpuk saat pesanan dibatalkan
            if ($pesanan->pembayaran) {
                $pesanan->pembayaran()->delete();
            }

            $pesanan->status  = 'dibatalkan';
            $pesanan->catatan = $request->catatan;
            $pesanan->save();

            foreach ($pesanan->detail as $detail) {
                $produk = Produk::find($detail->produk_id);
                if ($produk) {
                    $produk->stok += $detail->qty;
                    $produk->save();
                }
            }

            DB::commit();

            return redirect()->route('pesanan.index')
                ->with('success', 'Pesanan berhasil dibatalkan');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Gagal membatalkan pesanan: ' . $e->getMessage());
        }
    }

    // =========================
    // KONFIRMASI PENERIMAAN PESANAN
    // =========================
    public function selesai($id)
    {
        DB::beginTransaction();

        try {
            $pesanan = Pesanan::where('user_id', auth()->id())
                ->with('detail', 'kurirAssignment')
                ->findOrFail($id);

            $kurirSelesai = $pesanan->kurirAssignment && $pesanan->kurirAssignment->status == 'selesai';

            if ($pesanan->status !== 'dikirim') {
                return back()->with('error', 'Pesanan tidak dapat diterima karena statusnya ' . $pesanan->status);
            }

            if (!$kurirSelesai) {
                return back()->with('error', 'Kurir belum menyelesaikan pengiriman. Silakan tunggu konfirmasi dari kurir.');
            }

            $pesanan->status          = 'selesai';
            $pesanan->tanggal_selesai = now();
            $pesanan->save();

            Log::info('User menerima pesanan - status pesanan diubah ke SELESAI', [
                'pesanan_id' => $pesanan->id,
                'user_id'    => auth()->id(),
            ]);

            DB::commit();

            return redirect()->route('pesanan.index')
                ->with('success', 'Pesanan selesai! Terima kasih telah berbelanja di Raja Futsal.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Gagal menyelesaikan pesanan: ' . $e->getMessage());
        }
    }

    // =========================
    // CEK STATUS KURIR
    // =========================
    public function cekStatusKurir($id)
    {
        $pesanan = Pesanan::with('kurirAssignment')->findOrFail($id);

        $kurirSelesai     = $pesanan->kurirAssignment && $pesanan->kurirAssignment->status == 'selesai';
        $bisaDikonfirmasi = ($pesanan->status == 'dikirim' && $kurirSelesai);

        return response()->json([
            'success'           => true,
            'status_pesanan'    => $pesanan->status,
            'status_kurir'      => $pesanan->kurirAssignment->status ?? null,
            'bisa_dikonfirmasi' => $bisaDikonfirmasi,
            'pesan'             => $bisaDikonfirmasi
                ? 'Pesanan siap dikonfirmasi'
                : 'Menunggu kurir menyelesaikan pengiriman',
        ]);
    }

    // =========================
    // RIWAYAT PESANAN SELESAI
    // =========================
    public function riwayat()
    {
        $pesanan = Pesanan::with(['alamat', 'detail.produk', 'kurirAssignment'])
            ->where('user_id', auth()->id())
            ->where('status', 'selesai')
            ->latest()
            ->paginate(10);

        return view('pesanan.riwayat', compact('pesanan'));
    }

    // =========================
    // DETAIL PESANAN (UNTUK SELLER)
    // =========================
    public function detail($id)
    {
        $pesanan = Pesanan::with(['detail.produk', 'user', 'alamat', 'kurirAssignment'])
            ->findOrFail($id);

        return view('pesanan.detail', compact('pesanan'));
    }

    // =========================
    // CETAK RESI
    // =========================
    public function cetakResi(Request $request, $id)
    {
        $pesanan = Pesanan::with([
            'user',
            'detail.produk',
            'alamat.province',
            'alamat.city',
            'alamat.district',
            'alamat.village',
            'pembayaran',
            'kurirAssignment',
        ])
            ->where('user_id', auth()->id())
            ->findOrFail($id);

        if (!in_array($pesanan->status, ['dibayar', 'diproses', 'dikirim', 'selesai'])) {
            return back()->with('error', 'Resi hanya tersedia untuk pesanan yang sudah dibayar.');
        }

        $toko = null;
        if ($pesanan->detail->isNotEmpty() && $pesanan->detail->first()->produk) {
            $toko = \App\Models\Toko::with('province')
                ->where('user_id', $pesanan->detail->first()->produk->user_id)
                ->first();
        }

        $subtotalProduk = $pesanan->detail->sum(fn($d) => $d->harga * $d->qty);

        $diskon               = 0;
        $keteranganDiskon     = null;
        $subtotalSetelahDiskon = $subtotalProduk;

        if ($pesanan->catatan) {
            $catatan = json_decode($pesanan->catatan, true);
            if (isset($catatan['diskon'])) {
                $diskon               = $catatan['diskon'];
                $keteranganDiskon     = $catatan['keterangan'] ?? null;
                $subtotalSetelahDiskon = $catatan['subtotal_setelah_diskon'] ?? $subtotalProduk;
            }
        }

        $ongkir = $pesanan->total_harga - $subtotalSetelahDiskon;

        $pdf = Pdf::loadView('pesanan.resi', compact(
            'pesanan', 'toko', 'subtotalProduk', 'ongkir',
            'diskon', 'keteranganDiskon', 'subtotalSetelahDiskon'
        ))
            ->setPaper('A5', 'portrait')
            ->setOptions([
                'defaultFont'          => 'Arial, sans-serif',
                'isRemoteEnabled'      => true,
                'isHtml5ParserEnabled' => true,
                'dpi'                  => 96,
            ]);

        if ($request->get('preview') == '1') {
            return $pdf->stream('resi-' . $pesanan->kode_pesanan . '.pdf');
        }

        return $pdf->download('resi-' . $pesanan->kode_pesanan . '.pdf');
    }

    // =========================
    // CETAK RESI (UNTUK PENJUAL)
    // =========================
    public function cetakResiPenjual(Request $request, $id)
    {
        $pesanan = Pesanan::with([
            'user',
            'detail.produk',
            'alamat.province',
            'alamat.city',
            'alamat.district',
            'alamat.village',
            'pembayaran',
            'kurirAssignment',
        ])
            ->findOrFail($id);

        $hasMyProduct = $pesanan->detail->contains(function ($detail) {
            return $detail->produk && $detail->produk->user_id == auth()->id();
        });

        if (!$hasMyProduct) {
            abort(403, 'Anda tidak memiliki akses ke pesanan ini');
        }

        if (!in_array($pesanan->status, ['dibayar', 'diproses', 'dikirim', 'selesai'])) {
            return back()->with('error', 'Resi hanya tersedia untuk pesanan yang sudah dibayar.');
        }

        $toko = null;
        if ($pesanan->detail->isNotEmpty() && $pesanan->detail->first()->produk) {
            $toko = \App\Models\Toko::with('province')
                ->where('user_id', $pesanan->detail->first()->produk->user_id)
                ->first();
        }

        $subtotalProduk = $pesanan->detail->sum(fn($d) => $d->harga * $d->qty);

        $diskon               = 0;
        $keteranganDiskon     = null;
        $subtotalSetelahDiskon = $subtotalProduk;

        if ($pesanan->catatan) {
            $catatan = json_decode($pesanan->catatan, true);
            if (isset($catatan['diskon'])) {
                $diskon               = $catatan['diskon'];
                $keteranganDiskon     = $catatan['keterangan'] ?? null;
                $subtotalSetelahDiskon = $catatan['subtotal_setelah_diskon'] ?? $subtotalProduk;
            }
        }

        $ongkir = $pesanan->total_harga - $subtotalSetelahDiskon;

        $pdf = Pdf::loadView('pesanan.resi', compact(
            'pesanan', 'toko', 'subtotalProduk', 'ongkir',
            'diskon', 'keteranganDiskon', 'subtotalSetelahDiskon'
        ))
            ->setPaper('A5', 'portrait')
            ->setOptions([
                'defaultFont'          => 'Arial, sans-serif',
                'isRemoteEnabled'      => true,
                'isHtml5ParserEnabled' => true,
                'dpi'                  => 96,
            ]);

        if ($request->get('preview') == '1') {
            return $pdf->stream('resi-penjual-' . $pesanan->kode_pesanan . '.pdf');
        }

        return $pdf->download('resi-penjual-' . $pesanan->kode_pesanan . '.pdf');
    }

    // =========================
    // CETAK INVOICE
    // =========================
    public function cetakInvoice(Request $request, $id)
    {
        $pesanan = Pesanan::with([
            'user',
            'detail.produk',
            'alamat.province',
            'alamat.city',
            'alamat.district',
            'alamat.village',
            'pembayaran',
            'kurir',
            'kurirAssignment',
        ])->findOrFail($id);

        $toko = null;
        if ($pesanan->detail->isNotEmpty() && $pesanan->detail->first()->produk) {
            $toko = \App\Models\Toko::with('province')
                ->where('user_id', $pesanan->detail->first()->produk->user_id)
                ->first();
        }

        $subtotalProduk = $pesanan->detail->sum(fn($d) => $d->harga * $d->qty);

        $diskon               = 0;
        $keteranganDiskon     = null;
        $subtotalSetelahDiskon = $subtotalProduk;

        $jarakKm           = 0;
        $totalBerat        = 0;
        $kategoriProvinsi  = '-';
        $ongkirDetail      = null;
        $biayaJarak        = 0;
        $biayaBerat        = 0;
        $biayaProvinsi     = 0;

        if ($pesanan->catatan) {
            $catatan = json_decode($pesanan->catatan, true);
            if (isset($catatan['diskon'])) {
                $diskon                = $catatan['diskon'];
                $keteranganDiskon      = $catatan['keterangan'] ?? null;
                $subtotalSetelahDiskon = $catatan['subtotal_setelah_diskon'] ?? $subtotalProduk;
            }
            $jarakKm          = $catatan['jarak_km'] ?? $catatan['jarak'] ?? 0;
            $totalBerat       = $catatan['rincian']['berat_gram'] ?? $catatan['berat_gram'] ?? $catatan['total_berat'] ?? $catatan['berat'] ?? 0;
            $kategoriProvinsi = $catatan['kategori_provinsi'] ?? $catatan['kategori'] ?? '-';
            $ongkirDetail     = $catatan['detail'] ?? null;
            $biayaJarak       = $catatan['biaya_jarak'] ?? 0;
            $biayaBerat       = $catatan['biaya_berat'] ?? 0;
            $biayaProvinsi    = $catatan['biaya_provinsi'] ?? 0;
        }

        // Fallback: hitung berat dari detail produk jika catatan tidak ada / 0
        if (!$totalBerat) {
            $totalBerat = $pesanan->detail->sum(function ($d) {
                return ($d->produk->berat ?? 0) * $d->qty;
            });
        }

        $ongkir = $pesanan->total_harga - $subtotalSetelahDiskon;

        if ($request->get('mode') === 'html') {
            return view('pesanan.invoice_html', compact(
                'pesanan', 'toko', 'subtotalProduk', 'ongkir',
                'diskon', 'keteranganDiskon', 'subtotalSetelahDiskon',
                'jarakKm', 'totalBerat', 'kategoriProvinsi', 'ongkirDetail',
                'biayaJarak', 'biayaBerat', 'biayaProvinsi'
            ));
        }

        $pdf = Pdf::loadView('pesanan.invoice', compact(
            'pesanan', 'toko', 'subtotalProduk', 'ongkir',
            'diskon', 'keteranganDiskon', 'subtotalSetelahDiskon',
            'jarakKm', 'totalBerat', 'kategoriProvinsi', 'ongkirDetail',
            'biayaJarak', 'biayaBerat', 'biayaProvinsi'
        ))
            ->setPaper('A4', 'portrait')
            ->setOptions([
                'defaultFont'          => 'Arial, sans-serif',
                'isRemoteEnabled'      => true,
                'isHtml5ParserEnabled' => true,
                'dpi'                  => 96,
            ]);

        if ($request->get('preview') == '1') {
            return $pdf->stream('invoice-' . $pesanan->kode_pesanan . '.pdf');
        }

        return $pdf->download('invoice-' . $pesanan->kode_pesanan . '.pdf');
    }

    // =========================
    // KIRIM INVOICE VIA EMAIL (UNTUK SELLER)
    // =========================
    public function kirimInvoice($id)
    {
        try {
            $pesanan = Pesanan::with(['user', 'detail.produk', 'alamat'])->findOrFail($id);

            // Access check
            $uid = auth()->id();
            $hasMyProduct = $pesanan->detail->contains(function ($detail) use ($uid) {
                return $detail->produk && $detail->produk->user_id == $uid;
            });

            if (!$hasMyProduct) {
                return response()->json(['success' => false, 'message' => 'Anda tidak memiliki akses ke pesanan ini'], 403);
            }

            if (!in_array($pesanan->status, ['dibayar', 'diproses', 'dikirim'])) {
                return response()->json(['success' => false, 'message' => 'Invoice hanya dapat dikirim untuk pesanan dengan status Dibayar, Diproses, atau Dikirim'], 400);
            }

            if ($pesanan->invoice_sent_at) {
                return response()->json(['success' => false, 'message' => 'Invoice sudah pernah dikirim sebelumnya'], 400);
            }

            $success = $this->generateAndSendInvoice($pesanan);

            if ($success) {
                return response()->json([
                    'success' => true,
                    'message' => 'Invoice berhasil dikirim ke ' . $pesanan->user->email,
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => 'Gagal mengirim invoice. Silakan coba lagi nanti.',
                ], 500);
            }

        } catch (\Exception $e) {
            Log::error('Kirim Invoice Error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Kesalahan sistem: ' . $e->getMessage(),
            ], 500);
        }
    }
}