<?php

namespace App\Livewire;

use Livewire\Component;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use App\Models\Items;
use App\Models\TypeItems;
use App\Models\Order;
use App\Models\OrderItem;
use Midtrans\Config;
use Midtrans\Snap;
use App\Mail\OrderReceiptMail;
use Carbon\Carbon;
use Kreait\Firebase\Factory;

class FoodOrder extends Component
{
    public array $cart = [];
    public bool $showCart = false;
    public ?int $typeItemId = null;
    public bool $showEmailInput = true;
    public string $customerEmail = '';
    public $isExistingCustomer = '0';

    public ?string $selectedTableId = null;
    public ?string $selectedOccupiedTableId = null;
    public string $inputCustomerName = '';
    public bool $showCustomerNameInput = false;
    public bool $isCustomerNameInputDisabled = false;
    public array $availableTables = [];
    public array $occupiedTables = [];
    public Collection $allTablesData;
    public bool $showMapModal = false;
    public ?string $tableIdFromUrl = null;
    public $showQrisPayment = false;
    public $qrisImageUrl = 'img/qr-code.png';
    public bool $paymentInProgress = false;

    public bool $showCheckoutDetailsModal = false;
    public ?string $selectedPaymentMethod = null;

    private array $lastFirebaseDataHash = [];

    protected function rules()
    {
        return [
            'inputCustomerName' => 'required|string|min:3',
            'customerEmail' => 'nullable|email|max:255',
            'selectedTableId' => 'required_without:selectedOccupiedTableId',
            'selectedOccupiedTableId' => 'required_without:selectedTableId',
            'selectedPaymentMethod' => 'required|in:midtrans,cash,qris',
        ];
    }

    protected function messages()
    {
        return [
            'inputCustomerName.required' => 'Nama pemesan wajib diisi.',
            'inputCustomerName.min' => 'Nama pemesan minimal 3 karakter.',
            'selectedTableId.required_without' => 'Mohon pilih meja untuk pesanan.',
            'selectedOccupiedTableId.required_without' => 'Mohon pilih meja untuk pesanan.',
            'customerEmail.email' => 'Format email tidak valid.',
            'selectedPaymentMethod.required' => 'Mohon pilih metode pembayaran.',
            'selectedPaymentMethod.in' => 'Metode pembayaran tidak valid.',
        ];
    }
    protected $listeners = [
        'paymentSuccess' => 'handlePaymentSuccess',            // misalnya untuk pembayaran tunai/manual
        'midtransPaymentSuccess' => 'handleMidtransSuccess',   // khusus untuk callback Snap Midtrans
        'tableStatusUpdated' => 'syncTablesFromFirebase',      // untuk update status meja via Firebase
        'resetCartAfterOrder' => 'clearCartAndResetState'
    ];

    public function mount($typeSlug = null)
    {
        $this->cart = session()->get('cart', []);
        $this->allTablesData = collect();
        $this->syncTablesFromFirebase();

        $this->tableIdFromUrl = request()->query('table_id');

        $type = $typeSlug
            ? TypeItems::whereRaw('LOWER(REPLACE(name, " ", "-")) = ?', [Str::lower($typeSlug)])->first()
            : TypeItems::whereRaw('LOWER(REPLACE(name, " ", "-")) = ?', ['makanan'])->first();

        $this->typeItemId = $type->id ?? null;

        if (empty($this->customerEmail)) {
            $this->customerEmail = 'guest@gmail.com';
        }
    }

    public function getIsExistingCustomerBoolProperty(): bool
    {
        return $this->isExistingCustomer === '1';
    }

    private function getFirebaseDatabase()
    {
        try {
            $path = config('services.firebase.credentials');
            $path = file_exists($path) ? $path : storage_path('app/' . $path);
            throw_unless(file_exists($path), new \Exception("Firebase credentials not found at: $path"));

            return (new Factory)
                ->withServiceAccount($path)
                ->withDatabaseUri(config('services.firebase.database_url'))
                ->createDatabase();
        } catch (\Exception $e) {
            Log::error("Firebase init failed: " . $e->getMessage());
            $this->dispatch('notify', message: 'Gagal koneksi Firebase: ' . $e->getMessage(), type: 'error');
            $this->dispatch('logToConsole', message: 'ERROR: Firebase init failed: ' . $e->getMessage());
            return null;
        }
    }

    public function syncTablesFromFirebase()
    {
        $db = $this->getFirebaseDatabase();
        if (!$db) {
            return $this->resetTables();
        }

        try {
            $data = $db->getReference('/')->getValue();

            if (empty($data)) {
                $this->dispatch('logToConsole', message: 'Firebase data is empty, resetting tables.');
                return $this->resetTables();
            }

            $currentHash = md5(json_encode($data));
            if (($this->lastFirebaseDataHash['tables'] ?? null) === $currentHash) {
                return;
            }

            // Only process if data changed significantly
            $this->processFirebaseData($data);
            $this->lastFirebaseDataHash['tables'] = $currentHash;

        } catch (\Exception $e) {
            Log::error("Sync Firebase failed: " . $e->getMessage());
            $this->dispatch('notify', message: 'Gagal sinkron Firebase: ' . $e->getMessage(), type: 'error');
            $this->resetTables();
        }
    }

    private function processFirebaseData($data)
    {
        $available = $occupied = $all = [];

        foreach ($data as $id => $d) {
            $isActive = (bool)($d['sensors']['table_activation_sensor_active'] ?? false);
            $reservedBy = $d['reserved_by'] ?? null;
            $reservedBy = ($reservedBy === 'N/A' || empty($reservedBy)) ? null : $reservedBy;

            $table = [
                'id' => $id,
                'device_id' => $d['device_id'] ?? $id,
                'table_activation_sensor_active' => $isActive,
                'reserved_by' => $reservedBy,
                'is_available' => !$isActive && empty($reservedBy),
                'is_occupied_by_someone' => $isActive && !empty($reservedBy),
                'is_occupied_but_empty_reserved' => $isActive && empty($reservedBy),
                'firebase_data' => $d
            ];

            $all[$id] = $table;

            if ($table['is_available']) {
                $available[] = $table;
            } elseif ($table['is_occupied_by_someone']) {
                $occupied[] = $table;
            }
        }

        $this->availableTables = $available;
        $this->occupiedTables = $occupied;
        $this->allTablesData = collect($all);
        $this->attemptAutoSelectTable();
    }

    private function resetTables()
    {
        $this->availableTables = [];
        $this->occupiedTables = [];
        $this->allTablesData = collect();
        $this->selectedTableId = null;
        $this->selectedOccupiedTableId = null;
        $this->inputCustomerName = '';
        $this->isExistingCustomer = false;
        $this->showCustomerNameInput = false;
        $this->isCustomerNameInputDisabled = false;
        $this->tableIdFromUrl = null;
        $this->dispatch('logToConsole', message: 'Tables reset.');
    }

    private function attemptAutoSelectTable()
    {
        if (!$this->tableIdFromUrl || $this->allTablesData->isEmpty()) {
            $this->dispatch('logToConsole', message: 'No table_id from URL or tables data empty. Skipping auto-select.');
            return;
        }

        $table = $this->allTablesData->firstWhere('device_id', $this->tableIdFromUrl);
        if (!$table) {
            $this->dispatch('notify', message: 'Meja dengan ID "' . $this->tableIdFromUrl . '" tidak ditemukan.', type: 'warning');
            $this->tableIdFromUrl = null;
            $this->dispatch('logToConsole', message: 'Auto-select aborted: Table ' . $this->tableIdFromUrl . ' not found.');
            return;
        }

        $this->dispatch('logToConsole', message: 'Attempting to auto-select table: ' . $this->tableIdFromUrl . ' with data: ' . json_encode($table));

        if ($table['is_available']) {
            $this->selectedTableId = $table['id'];
            $this->selectedOccupiedTableId = null;
            $this->isExistingCustomer = false;
            $this->inputCustomerName = '';
            $this->showCustomerNameInput = true;
            $this->isCustomerNameInputDisabled = false;
            $this->dispatch('notify', message: 'Meja ' . $table['device_id'] . ' berhasil dipilih otomatis sebagai meja baru.', type: 'success');
            $this->dispatch('logToConsole', message: 'Auto-selected available table: ' . $table['device_id']);
        } elseif ($table['is_occupied_by_someone']) {
            $this->selectedOccupiedTableId = $table['id'];
            $this->selectedTableId = null;
            $this->isExistingCustomer = true;
            $this->inputCustomerName = $table['reserved_by'];
            $this->isCustomerNameInputDisabled = true;
            $this->dispatch('notify', message: 'Meja ' . $table['device_id'] . ' sudah terisi oleh ' . $table['reserved_by'] . '.', type: 'info');
            $this->dispatch('logToConsole', message: 'Auto-selected occupied table with reservation: ' . $table['device_id'] . ' by ' . $table['reserved_by']);
        } elseif ($table['is_occupied_but_empty_reserved']) {
            $this->selectedOccupiedTableId = $table['id'];
            $this->selectedTableId = null;
            $this->isExistingCustomer = true;
            $this->inputCustomerName = '';
            $this->showCustomerNameInput = true;
            $this->isCustomerNameInputDisabled = false;
            $this->dispatch('notify', message: 'Meja ' . $table['device_id'] . ' terisi tetapi nama pemesan belum terdaftar. Mohon masukkan nama Anda.', type: 'warning');
            $this->dispatch('logToConsole', message: 'Auto-selected occupied table without reservation: ' . $table['device_id'] . '. Customer needs to input name.');
        } else {
            $this->dispatch('notify', message: 'Meja ' . $table['device_id'] . ' tidak tersedia atau tidak dikenal.', type: 'warning');
            $this->dispatch('logToConsole', message: 'Auto-select failed for table: ' . $table['device_id'] . '. Not available or unknown state.');
        }
        $this->tableIdFromUrl = null;
    }

    public function showMap()
    {
        $this->showMapModal = true;
        $this->dispatch('logToConsole', message: 'Showing map modal.');
    }

    public function closeMap()
    {
        $this->showMapModal = false;
        $this->dispatch('logToConsole', message: 'Closing map modal.');
    }

    public function updatedSelectedTableId($value)
    {
        $this->resetErrorBag(['selectedTableId', 'selectedOccupiedTableId', 'inputCustomerName']);
        $this->selectedOccupiedTableId = null;
        $this->isExistingCustomer = false;

        if ($value) {
            $this->showCustomerNameInput = true;
            $this->isCustomerNameInputDisabled = false;
            $this->inputCustomerName = '';
            $this->dispatch('logToConsole', message: "Meja kosong dipilih: " . $value . ". Nama default: " . ($this->inputCustomerName ?: 'Kosong'));
        } else {
            $this->showCustomerNameInput = false;
            $this->inputCustomerName = '';
            $this->dispatch('logToConsole', message: "Meja kosong tidak dipilih.");
        }
        $this->showEmailInput = true;
    }

    public function updatedSelectedOccupiedTableId($value)
    {
        $this->resetErrorBag(['selectedTableId', 'selectedOccupiedTableId', 'inputCustomerName']);
        $this->selectedTableId = null;
        $this->isExistingCustomer = true;

        if ($value) {
            $selectedTable = $this->allTablesData->get($value);
            if ($selectedTable) {
                $this->showCustomerNameInput = true;
                if ($selectedTable['is_occupied_by_someone']) {
                    $this->inputCustomerName = $selectedTable['reserved_by'];
                    $this->isCustomerNameInputDisabled = true;
                    $this->dispatch('notify', message: 'Nama pemesan otomatis terisi: ' . $selectedTable['reserved_by'] . '.', type: 'info');
                    $this->dispatch('logToConsole', message: "Meja terisi dipilih dengan reservasi: " . $value . ". Nama: " . $this->inputCustomerName);
                } elseif ($selectedTable['is_occupied_but_empty_reserved']) {
                    $this->inputCustomerName = '';
                    $this->isCustomerNameInputDisabled = false;
                    $this->dispatch('notify', message: 'Meja ini terisi, namun nama pemesan belum terdaftar. Mohon masukkan nama Anda.', type: 'warning');
                    $this->dispatch('logToConsole', message: "Meja terisi dipilih tanpa reservasi: " . $value . ". Customer needs to input name.");
                } else {
                    $this->inputCustomerName = '';
                    $this->showCustomerNameInput = false;
                    $this->isExistingCustomer = false;
                    $this->dispatch('notify', message: 'Kesalahan: Meja yang dipilih tidak valid sebagai meja terisi. Silakan pilih ulang.', type: 'error');
                    $this->selectedOccupiedTableId = null;
                    $this->dispatch('logToConsole', message: "Invalid occupied table selected: " . $value . ". Resetting selection.");
                }
            } else {
                 $this->dispatch('notify', message: 'Meja yang dipilih tidak ditemukan.', type: 'error');
                 $this->selectedOccupiedTableId = null;
                 $this->inputCustomerName = '';
                 $this->showCustomerNameInput = false;
                 $this->isExistingCustomer = false;
                 $this->dispatch('logToConsole', message: "Selected occupied table not found: " . $value . ". Resetting selection.");
            }
        } else {
            $this->showCustomerNameInput = false;
            $this->inputCustomerName = '';
            $this->isExistingCustomer = false;
            $this->dispatch('logToConsole', message: "Meja terisi tidak dipilih.");
        }
        $this->showEmailInput = true;
    }

    public function updatedIsExistingCustomer($value)
    {
        $this->selectedTableId = null;
        $this->selectedOccupiedTableId = null;
        $this->inputCustomerName = '';
        $this->showCustomerNameInput = false;
        $this->isCustomerNameInputDisabled = false;
        $this->resetErrorBag(['selectedTableId', 'selectedOccupiedTableId', 'inputCustomerName']);

        if (!$value) {
            $this->showCustomerNameInput = true;
            $this->isCustomerNameInputDisabled = false;
            $this->inputCustomerName = '';
            $this->dispatch('logToConsole', message: "isExistingCustomer changed to NEW. Input name displayed.");
        } else {
            $this->showCustomerNameInput = false;
            $this->inputCustomerName = '';
            $this->dispatch('logToConsole', message: "isExistingCustomer changed to EXISTING. Input name hidden until table selected.");
        }
        $this->showEmailInput = true;
    }

    public function goToCheckoutDetails()
    {
        if (empty($this->cart)) {
            $this->dispatch('notify', message: 'Keranjang belanja Anda kosong. Silakan tambahkan item.');
            return;
        }
        $this->showCheckoutDetailsModal = true;
        $this->dispatch('logToConsole', message: 'Proceeding to checkout details.');
    }

    public function closeCheckoutDetailsModal()
    {
        $this->showCheckoutDetailsModal = false;
        $this->dispatch('logToConsole', message: 'Checkout details modal closed.');
    }

    public function processOrderConfirmation()
    {
        $this->dispatch('logToConsole', message: 'Memulai proses konfirmasi order...');
        $cartItems = $this->getCartItemsProperty();

        if (empty($cartItems) && !$this->paymentInProgress) return;

        try {
            $this->validate();
        } catch (ValidationException $e) {
            foreach ($e->errors() as $field => $messages) {
                foreach ($messages as $message) {
                    $this->dispatch('notify', message: $message, type: 'error');
                }
            }
            return;
        }

        $selectedTableData = $this->getSelectedTableForTransaction();
        if (!$selectedTableData) {
            $this->dispatch('notify', message: 'Detail meja tidak ditemukan.', type: 'error');
            return;
        }

        $isSensorActive = (bool)($selectedTableData['firebase_data']['sensors']['table_activation_sensor_active'] ?? false);
        $reservedBy = $selectedTableData['reserved_by'];

        if ($this->isExistingCustomer) {
            if (!$isSensorActive) {
                $this->dispatch('notify', message: 'Meja ini belum terisi.', type: 'warning');
                return;
            }
            if (!empty($reservedBy) && Str::lower($this->inputCustomerName) !== Str::lower($reservedBy)) {
                $this->dispatch('notify', message: 'Nama tidak cocok dengan reservasi: ' . $reservedBy, type: 'warning');
                return;
            }
        } else {
            if ($isSensorActive) {
                $this->dispatch('notify', message: 'Meja sudah terisi, pilih meja lain.', type: 'warning');
                return;
            }
        }

        if (empty($this->customerEmail)) {
            $this->customerEmail = 'guest@gmail.com';
        }

        $totalAmount = $this->getCartTotalProperty();

        if ($this->selectedPaymentMethod === 'midtrans' && $totalAmount < 10000) {
            $this->dispatch('notify', message: 'Minimum Midtrans Rp 10.000', type: 'error');
            return;
        }

        try {
            $waktuWIB = now()->timezone('Asia/Jakarta');
            if ($this->selectedPaymentMethod === 'midtrans'){
                $midtransTransactionId = 'MIDTRANS-' . now()->timestamp . '-' . rand(1000, 9999);
            }

            // Buat order terlebih dahulu (baik untuk midtrans maupun metode lain)
            $order = Order::create([
                'customer_name' => $this->inputCustomerName,
                'customer_email' => $this->customerEmail,
                'table_id' => $selectedTableData['id'],
                'total_amount' => $totalAmount,
                'transaction_status' => 'pending',
                'payment_method' => $this->selectedPaymentMethod,
                'midtrans_transaction_id' => $midtransTransactionId ?? null,
                'created_at' => $waktuWIB,
                'updated_at' => $waktuWIB,
            ]);

            foreach ($cartItems as $item) {
                OrderItem::create([
                    'order_id' => $order->id,
                    'item_id' => $item['id'],
                    'item_name' => $item['name'],
                    'item_price' => $item['price'],
                    'quantity' => $item['qty'],
                    'total_price' => $item['total_price'],
                    'created_at' => $waktuWIB,
                    'updated_at' => $waktuWIB,
                ]);
            }

            if ($this->selectedPaymentMethod === 'midtrans') {
                $this->paymentInProgress = true;

                $this->clearCartAndResetState();
                return redirect()->route('midtrans.payment', [
                    'midtrans_transaction_id' => $midtransTransactionId,
                ]);

            } elseif ($this->selectedPaymentMethod === 'qris') {
                $this->processQrisPayment($order->id);
            } else {
                $this->processManualPaymentInternal($order->id);
            }
        } catch (\Exception $e) {
            Log::error("Gagal membuat order: " . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
            $this->dispatch('notify', message: 'Gagal memproses pesanan: ' . $e->getMessage(), type: 'error');
        }
    }

    public function updateFirebaseTableStatus(string $firebaseTableId, array $updates, bool $refresh = true)
    {
        $database = $this->getFirebaseDatabase();
        if (!$database) return;

        try {
            $database->getReference($firebaseTableId)->update($updates);
            $this->dispatch('logToConsole', message: "Firebase: Updated {$firebaseTableId} with " . json_encode($updates));
            $this->dispatch('notify', message: "Status meja '{$firebaseTableId}' berhasil diperbarui di Firebase.", type: 'success');

            if ($refresh) {
                $this->syncTablesFromFirebase();
            }
        } catch (\Exception $e) {
            Log::error("Failed to update Firebase for table ID {$firebaseTableId}: " . $e->getMessage());
            $this->dispatch('logToConsole', message: 'ERROR: Failed to update Firebase for table ID ' . $firebaseTableId . ': ' . $e->getMessage());
            $this->dispatch('notify', message: 'Gagal memperbarui status meja di Firebase: ' . $e->getMessage(), type: 'error');
        }
    }

    protected function initiateMidtransPayment($midtransTransactionId, $totalAmount, array $selectedTableData, array $cartItems): Redirector|null
    {
        $this->dispatch('logToConsole', message: 'Memulai pembayaran Midtrans...');

        try {
            if (empty($midtransTransactionId)) {
                throw new \Exception('ID transaksi Midtrans tidak boleh kosong.');
            }

            if ($totalAmount < 10000) {
                throw new \Exception('Minimum pembayaran Midtrans adalah Rp 10.000');
            }

            if (empty($cartItems)) {
                throw new \Exception('Keranjang belanja kosong');
            }

            // Data customer
            $customerDetails = [
                'first_name' => substr($this->inputCustomerName ?: 'Customer', 0, 50),
                'email' => $this->customerEmail ?: 'guest@gmail.com',
                'phone' => '08123456789',
            ];

            // Item
            $itemDetails = array_map(fn($item) => [
                'id' => $item['id'],
                'price' => $item['price'],
                'quantity' => $item['qty'],
                'name' => substr($item['name'], 0, 50),
            ], $cartItems);

            $params = [
                'transaction_details' => [
                    'order_id' => (string) $midtransTransactionId,
                    'gross_amount' => $totalAmount,
                ],
                'customer_details' => $customerDetails,
                'item_details' => $itemDetails,
                'enabled_payments' => [
                    'credit_card',
                    'bca_va',
                    'bni_va',
                    'bri_va'
                ],
                'callbacks' => [
                    'finish' => url('/midtrans/finish'),
                    'error' => url('/midtrans/error'),
                    'pending' => url('/midtrans/pending'),
                ]
            ];
            session([
                'order_data' => [
                    'customer_name' => $this->inputCustomerName,
                    'customer_email' => $this->customerEmail,
                    'table_id' => $selectedTableData['id'],
                    'midtrans_transaction_id' => $midtransTransactionId,
                    'total_amount' => $totalAmount,
                    'payment_method' => 'midtrans',
                    'cart_items' => $cartItems,
                ]
            ]);

            // Konfigurasi Midtrans
            Config::$serverKey = config('services.midtrans.server_key');
            Config::$isProduction = config('services.midtrans.is_production', false);
            Config::$isSanitized = true;
            Config::$is3ds = true;

            // Snap Token
            $snapToken = Snap::getSnapToken($params);

            if (empty($snapToken)) {
                throw new \Exception('Gagal mendapatkan token pembayaran dari Midtrans');
            }

            // Redirect ke halaman Snap Midtrans
            return $this->redirectRoute('midtrans.payment.page', ['token' => $snapToken]);

        } catch (\Exception $e) {
            Log::error("Error Midtrans: " . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
            $this->dispatch('notify', message: 'Gagal memproses pembayaran: ' . $e->getMessage(), type: 'error');
            return null;
        }
    }

    protected function updateTableStatusToReserved(array $orderData): void
    {
        $firebase = $this->getFirebaseDatabase();
        if (!$firebase) {
            return;
        }

        try {
            $firebase->getReference($orderData['table_device_id'])->update([
                'reserved_by' => $orderData['customer_name'],
                'sensors/table_activation_sensor_active' => 1,
                'table_occupied' => 1,
            ]);
            \Log::info("Firebase: Meja {$orderData['table_device_id']} diupdate sebagai reserved oleh {$orderData['customer_name']}.");
        } catch (\Exception $e) {
            \Log::error("Gagal update status meja di Firebase: " . $e->getMessage());
            $this->dispatch('notify', message: 'Gagal update status meja di Firebase.', type: 'error');
        }
    }

    public function handleMidtransSuccess($result)
    {
        $selectedTableData = $this->getSelectedTableForTransaction();
        $totalAmount = $this->getCartTotalProperty();
        $cartItems = $this->getCartItemsProperty();

        // Simpan ke database
        $order = Order::create([
            'customer_name' => $this->inputCustomerName,
            'customer_email' => $this->customerEmail,
            'table_id' => $selectedTableData['id'],
            'total_amount' => $totalAmount,
            'payment_method' => 'midtrans',
            'midtrans_transaction_id' => $result['transaction_id'],
            'status' => 'confirmed',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        foreach ($cartItems as $item) {
            OrderItem::create([
                'order_id' => $order->id,
                'item_id' => $item['id'],
                'item_name' => $item['name'],
                'item_price' => $item['price'],
                'quantity' => $item['qty'],
                'total_price' => $item['total_price'],
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }

        // ✅ Tambahkan update ke Firebase di sini
        try {
            $firebase = (new \Kreait\Firebase\Factory)
                ->withServiceAccount(storage_path('app/firebase/.firebase_credentials.json'))
                ->createDatabase();

            $firebase->getReference($selectedTableData['device_id'])->update([
                'sensors/table_activation_sensor_active' => 1,
                'reserved_by' => $this->inputCustomerName,
            ]);
        } catch (\Exception $e) {
            // Logging atau tindakan jika gagal update ke Firebase
            \Log::error('Firebase update failed: ' . $e->getMessage());
        }

        // Bersihkan keranjang
        $this->resetCart();

        // Notifikasi
        $this->dispatch('notify', [
            'type' => 'success',
            'message' => 'Pembayaran berhasil!'
        ]);
    }

    protected function processManualPaymentInternal($orderDbId)
    {
        $paymentTypes = [
            'cash' => 'Pembayaran tunai berhasil. Silakan tunggu konfirmasi dari kasir.',
            'transfer' => 'Transfer berhasil. Mohon tunjukkan bukti ke kasir.',
            'qris' => 'QRIS berhasil. Mohon tunjukkan bukti ke kasir.',
        ];

        $message = $paymentTypes[$this->selectedPaymentMethod]
            ?? 'Pembayaran berhasil. Mohon tunggu konfirmasi dari kasir.';

        try {
            // Aktifkan flag agar tidak muncul "Keranjang kosong"
            $this->paymentInProgress = true;

            // Tutup modal checkout
            $this->closeCheckoutDetailsModal();

            // Tampilkan notifikasi sukses
            $this->dispatch('notify',
                message: $message,
                type: 'success'
            );

            // Reset tombol "Processing"
            $this->dispatch('resetProcessingButton');

            // Kosongkan keranjang setelah notifikasi
            $this->clearCartAndResetState();

            $order = \App\Models\Order::find($orderDbId);
            if ($order && $order->customer_email) {
                Mail::to($order->customer_email)->send(new OrderReceiptMail($order));
            }

        } catch (\Exception $e) {
            // Tangani error jika terjadi
            $this->dispatch('notify', [
                'message' => 'Terjadi kesalahan saat memproses pembayaran.',
                'type' => 'error',
            ]);
            $this->dispatch('resetProcessingButton');
        } finally {
            // Matikan flag walaupun error
            $this->paymentInProgress = false;
        }
    }

    protected function processQrisPayment($orderId)
    {
        $this->dispatch('logToConsole', message: 'Memulai pembayaran QRIS...');

        try {
            // Generate or get your static QRIS image URL
            // This could be from your payment gateway or a static image
            $this->qrisImageUrl = url('img/qr-code.png'); // Replace with actual QRIS image

            // Show the QRIS payment modal
            $this->showQrisPayment = true;

            $this->dispatch('notify',
                message: 'Silakan scan QRIS untuk melakukan pembayaran',
                type: 'info'
            );

        } catch (\Exception $e) {
            Log::error("Error QRIS: " . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
            $this->dispatch('notify',
                message: 'Gagal memproses pembayaran QRIS: ' . $e->getMessage(),
                type: 'error'
            );
        }
    }

    public function confirmQrisPayment()
    {
        try {
            // Here you would typically verify the payment with your payment gateway
            // For now we'll just simulate successful payment

            $this->showQrisPayment = false;
            $this->clearCartAndResetState();

            $this->dispatch('notify',
                message: 'Pembayaran QRIS berhasil dikonfirmasi!',
                type: 'success'
            );

        } catch (\Exception $e) {
            Log::error("QRIS confirmation error: " . $e->getMessage());
            $this->dispatch('notify',
                message: 'Gagal mengkonfirmasi pembayaran QRIS: ' . $e->getMessage(),
                type: 'error'
            );
        }
    }

    private function getSelectedTableData()
    {
        $tableId = $this->selectedTableId ?? $this->selectedOccupiedTableId;

        return $this->allTablesData->firstWhere('id', $tableId)?->toArray() ?? [
            'id' => null,
            'device_id' => null,
        ];
    }

    public function handlePaymentSuccess()
    {
        $this->clearCartAndResetState();
        $this->dispatch('notify', message: 'Pembayaran berhasil! Menunggu konfirmasi tolong konfirmasi ke kasir...', type: 'success');
    }

    protected function sendReceiptEmail($order)
    {
        try {
            if ($order->customer_email && filter_var($order->customer_email, FILTER_VALIDATE_EMAIL)) {
                Mail::to($order->customer_email)->send(new OrderReceipt($order));
                $this->dispatch('logToConsole', message: 'Order receipt email sent to ' . $order->customer_email);
            } else {
                $this->dispatch('logToConsole', message: 'No valid email provided for receipt.');
            }
        } catch (\Exception $e) {
            Log::error("Failed to send order receipt email: " . $e->getMessage());
            $this->dispatch('notify', message: 'Gagal mengirim struk ke email.', type: 'error');
        }
    }

    private function getSelectedTableForTransaction(): ?array
    {
        $tableId = $this->selectedTableId ?? $this->selectedOccupiedTableId;
        if (empty($tableId)) {
            $this->dispatch('logToConsole', message: 'No table ID selected for transaction.');
            return null;
        }
        $table = $this->allTablesData->get($tableId);
        if (!$table) {
            $this->dispatch('logToConsole', message: 'Table data not found for ID: ' . $tableId);
        } else {
            $this->dispatch('logToConsole', message: 'Selected table data for transaction: ' . json_encode($table));
        }
        return $table;
    }

    private function clearCartAndResetState()
    {
        $this->cart = [];
        session()->forget('cart');
        $this->showCart = false;
        $this->showEmailInput = true;
        $this->customerEmail = '';
        $this->selectedTableId = null;
        $this->selectedOccupiedTableId = null;
        $this->inputCustomerName = '';
        $this->isExistingCustomer = false;
        $this->showCustomerNameInput = false;
        $this->isCustomerNameInputDisabled = false;
        $this->resetValidation();
        $this->selectedPaymentMethod = null;
        $this->dispatch('logToConsole', message: 'Cart cleared and state reset.');
    }

    public function render()
    {
        return view('livewire.food-order', [
            'foodItems' => $this->getFilteredFoodItemsProperty(),
            'cartItems' => $this->getCartItemsProperty(),
            'cartTotal' => $this->getCartTotalProperty(),
            'pageTitle' => $this->getPageTitleProperty(),
            'typeItemId' => $this->typeItemId,
            'allTypeItems' => $this->getAllTypeItemsProperty(),
            'availableTables' => $this->availableTables,
            'occupiedTables' => $this->occupiedTables,
            'allTablesData' => $this->allTablesData->toArray(),
            'tableIdFromUrl' => $this->tableIdFromUrl,
        ])->layout('components.layouts.front');
    }

    public function getFoodItemsProperty()
    {
        return Cache::remember('food_items_'.$this->typeItemId, now()->addHours(1), function() {
            if ($this->typeItemId) {
                return Items::where('type_item_id', $this->typeItemId)->get();
            }
            return Items::all();
        });
    }

    public function getAllTypeItemsProperty()
    {
        return Cache::remember('all_type_items', now()->addHours(6), function() {
            return TypeItems::all();
        });
    }

    public function getFilteredFoodItemsProperty()
    {
        if ($this->typeItemId) {
            return Items::where('type_item_id', $this->typeItemId)->get();
        }
        return Items::all();
    }

    public function getCartItemsProperty()
    {
        $items = [];
        foreach ($this->cart as $itemId => $qty) {
            $item = Items::find($itemId);
            if ($item) {
                $items[] = [
                    'id' => $item->id,
                    'name' => $item->name,
                    'price' => $item->price,
                    'qty' => $qty,
                    'total_price' => $item->price * $qty,
                ];
            }
        }
        return $items;
    }

    public function getCartTotalProperty()
    {
        return collect($this->getCartItemsProperty())->sum('total_price');
    }

    public function getPageTitleProperty()
    {
        if ($this->typeItemId) {
            $type = TypeItems::find($this->typeItemId);
            return $type ? $type->name : 'Semua Menu';
        }
        return 'Semua Menu';
    }

    public function addToCart($itemId)
    {
        $item = Items::find($itemId);
        if (!$item) {
            $this->dispatch('notify', message: 'Item tidak ditemukan.', type: 'error');
            $this->dispatch('logToConsole', message: 'Failed to add to cart: Item ' . $itemId . ' not found.');
            return;
        }

        $this->cart[$itemId] = ($this->cart[$itemId] ?? 0) + 1;
        session()->put('cart', $this->cart);
        $this->dispatch('notify', message: $item->name . ' ditambahkan ke keranjang.', type: 'success');
        $this->dispatch('logToConsole', message: 'Added ' . $item->name . ' to cart. Current cart: ' . json_encode($this->cart));
    }

    public function removeFromCart($itemId)
    {
        if (isset($this->cart[$itemId])) {
            $item = Items::find($itemId);
            if ($this->cart[$itemId] > 1) {
                $this->cart[$itemId]--;
                $message = ($item->name ?? 'Item') . ' dikurangi dari keranjang.';
            } else {
                unset($this->cart[$itemId]);
                $message = ($item->name ?? 'Item') . ' dihapus dari keranjang.';
            }
            session()->put('cart', $this->cart);
            $this->dispatch('notify', message: $message, type: 'info');

            $this->dispatch('logToConsole', message: $message . '. Current cart: ' . json_encode($this->cart));

            if (empty($this->cart)) {
                $this->showCart = false;
                $this->dispatch('logToConsole', message: 'Cart is now empty. Closing cart view.');
            }
        } else {
            $this->dispatch('logToConsole', message: 'Attempted to remove non-existent item ' . $itemId . ' from cart.');
            $this->dispatch('notify', message: 'Item tidak ditemukan di keranjang.', type: 'warning');
        }
    }

    public function openCart()
    {
        $this->showCart = true;
        $this->dispatch('logToConsole', message: 'Cart opened.');
    }

    public function closeCart()
    {
        $this->showCart = false;
        $this->dispatch('logToConsole', message: 'Cart closed.');
    }

    public function filterByType($typeId)
    {
        $this->typeItemId = $typeId;
        $type = TypeItems::find($typeId);
        if ($type) {
            $typeSlug = Str::slug($type->name);
            $newUrl = route('menu.byType', ['typeSlug' => $typeSlug], false);
            $this->dispatch('updateUrl', url: $newUrl);
            $this->dispatch('logToConsole', message: 'Filtered by type: ' . $type->name . ' (ID: ' . $typeId . '). URL updated.');
        } else {
            $this->dispatch('logToConsole', message: 'Attempted to filter by non-existent type ID: ' . $typeId);
            $this->dispatch('notify', message: 'Tipe menu tidak ditemukan.', type: 'warning');
        }
    }
}
