<?php

namespace App\Http\Controllers;

use App\Models\Order;
use App\Models\Payment;
use App\Notifications\InvoiceNotification;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class InvoiceController extends Controller
{
    /**
     * Cek apakah user boleh mengakses invoice order ini.
     * Aturan:
     *  - Admin selalu boleh.
     *  - Customer hanya boleh jika order miliknya DAN payment sudah 'paid'.
     *    (Jika metode cash & belum paid → tolak.)
     */
    private function authorizeInvoice(Order $order): void
    {
        $user = Auth::user();

        // Admin boleh akses semua
        if ($user->isAdmin()) {
            return;
        }

        // Harus pemilik order
        if ($order->user_id !== $user->id) {
            abort(403, 'Unauthorized');
        }

        // Harus sudah paid
        $payment = $order->payment;
        if (!$payment || !$payment->isPaid()) {
            abort(403, 'Invoice belum tersedia. Selesaikan pembayaran terlebih dahulu.');
        }
    }

    /**
     * Tampilkan invoice di browser (HTML preview).
     * GET /orders/{order}/invoice
     */
    public function show(Order $order)
    {
        $order->load(['user', 'items.product', 'payment', 'address']);

        $this->authorizeInvoice($order);

        return view('invoices.show', compact('order'));
    }

    /**
     * Download invoice sebagai PDF.
     * GET /orders/{order}/invoice/download
     */
    public function download(Order $order)
    {
        $order->load(['user', 'items.product', 'payment', 'address']);

        $this->authorizeInvoice($order);

        $pdf = $this->generatePdf($order);

        $filename = 'Invoice-Order-' . $order->order_id . '.pdf';

        return $pdf->download($filename);
    }

    /**
     * Stream / tampilkan PDF inline di browser.
     * GET /orders/{order}/invoice/pdf
     */
    public function stream(Order $order)
    {
        $order->load(['user', 'items.product', 'payment', 'address']);

        $this->authorizeInvoice($order);

        $pdf = $this->generatePdf($order);

        $filename = 'Invoice-Order-' . $order->order_id . '.pdf';

        return $pdf->stream($filename);
    }

    /**
     * Kirim invoice ke email customer.
     * POST /orders/{order}/invoice/send
     * Hanya admin yang boleh memicu pengiriman manual.
     * Pengiriman otomatis dipanggil dari PaymentController / webhook.
     */
    public function sendEmail(Order $order)
    {
        $order->load(['user', 'items.product', 'payment', 'address']);

        // Hanya admin yang bisa trigger kirim manual via route ini
        if (!Auth::user()->isAdmin()) {
            abort(403, 'Unauthorized');
        }

        $payment = $order->payment;
        if (!$payment || !$payment->isPaid()) {
            return back()->with('error', 'Invoice hanya dapat dikirim jika pembayaran sudah lunas.');
        }

        try {
            $this->dispatchInvoiceEmail($order);
            return back()->with('success', 'Invoice berhasil dikirim ke ' . $order->user->email);
        } catch (\Exception $e) {
            Log::error('Gagal kirim invoice email: ' . $e->getMessage(), [
                'order_id' => $order->order_id,
            ]);
            return back()->with('error', 'Gagal mengirim invoice: ' . $e->getMessage());
        }
    }

    /**
     * Dipanggil secara internal (dari PaymentController setelah payment confirmed).
     * Tidak ada route publik untuk method ini.
     */
    public function sendInvoiceAfterPayment(Order $order): void
    {
        try {
            $order->loadMissing(['user', 'items.product', 'payment', 'address']);

            $payment = $order->payment;

            // Guard: hanya kirim jika memang sudah paid
            if (!$payment || !$payment->isPaid()) {
                Log::warning('sendInvoiceAfterPayment dipanggil tapi payment belum paid', [
                    'order_id'       => $order->order_id,
                    'payment_status' => $payment?->status,
                ]);
                return;
            }

            $this->dispatchInvoiceEmail($order);

            Log::info('Invoice dikirim otomatis setelah payment confirmed', [
                'order_id' => $order->order_id,
                'email'    => $order->user->email,
            ]);
        } catch (\Exception $e) {
            // Jangan sampai error invoice membatalkan flow payment
            Log::error('Auto invoice email gagal: ' . $e->getMessage(), [
                'order_id' => $order->order_id,
            ]);
        }
    }

    // ── PRIVATE HELPERS ───────────────────────────────────────────────────────

    /**
     * Generate objek PDF dari view invoice.
     */
    private function generatePdf(Order $order): \Barryvdh\DomPDF\PDF
    {
        $pdf = Pdf::loadView('invoices.pdf', compact('order'))
            ->setPaper('a4', 'portrait')
            ->setOptions([
                'defaultFont'  => 'sans-serif',
                'isHtml5ParserEnabled' => true,
                'isRemoteEnabled'      => false,
            ]);

        return $pdf;
    }

    /**
     * Kirim notifikasi email dengan PDF terlampir.
     */
    private function dispatchInvoiceEmail(Order $order): void
    {
        $order->user->notify(new InvoiceNotification($order));
    }
}
