<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Reservasi;
use App\Models\Cart;
use App\Models\Transaksi;
use App\Models\TransaksiItem;
use App\Models\Meja;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class TransaksiController extends Controller
{
    // Menampilkan daftar transaksi
    public function index()
    {
        $transaksi = Transaksi::with(['reservasi'])
            ->where('user_id', auth()->id())
            ->orderBy('created_at', 'desc')
            ->get();

        return view('transaksi.index', compact('transaksi'));
    }

    // Menampilkan halaman transaksi berdasarkan ID reservasi
    public function show($id)
    {
        try {
            // Find the transaction with its relationships
            $transaksi = Transaksi::with(['reservasi.meja', 'items.menu', 'user'])
                ->where('user_id', auth()->id())
                ->findOrFail($id);
            
            if (!$transaksi) {
                throw new \Exception('Transaksi tidak ditemukan');
            }

            $reservasi = $transaksi->reservasi;
            if (!$reservasi) {
                throw new \Exception('Data reservasi tidak ditemukan');
            }

            $items = $transaksi->items;

            // Get Midtrans snap token if payment is pending
            $snapToken = null;
            if ($transaksi->status === 'pending') {
                $midtransService = new \App\Services\MidtransService();
                $snapToken = $midtransService->createTransaction($transaksi);
            }
            
            return view('transaksi', compact('transaksi', 'reservasi', 'items', 'snapToken'));
        } catch (\Exception $e) {
            Log::error('Error in TransaksiController@show: ' . $e->getMessage());
            return redirect()->route('menu.index')
                ->with('error', 'Terjadi kesalahan saat menampilkan transaksi: ' . $e->getMessage());
        }
    }

    // Simpan transaksi
    public function store(Request $request)
    {
        // Debug log
        Log::info('Transaksi Request:', $request->all());

        // Validasi input
        $validated = $request->validate([
            'meja_id' => 'required|exists:meja,id',
            'tanggal' => 'required|date|after_or_equal:today',
            'jam' => 'required|date_format:H:i',
            'durasi' => 'required|integer|min:1|max:4',
            'jumlah_orang' => 'required|integer|min:1',
            'payment_method' => 'required|in:cash,transfer,qris'
        ]);

        DB::beginTransaction();
        try {
            // Cek ketersediaan meja
            $meja = Meja::findOrFail($validated['meja_id']);
            if ($meja->status !== 'tersedia') {
                return back()->with('error', 'Maaf, meja ini sudah tidak tersedia');
            }

            // Cek kapasitas meja
            if ($validated['jumlah_orang'] > $meja->kapasitas) {
                return back()->with('error', 'Jumlah orang melebihi kapasitas meja');
            }

            // Ambil items dari cart
            $cartItems = Cart::where('user_id', auth()->id())
                ->with('menu')
                ->get();

            Log::info('Cart Items:', $cartItems->toArray());

            if ($cartItems->isEmpty()) {
                return back()->with('error', 'Keranjang belanja kosong');
            }

            // Hitung total amount
            $totalAmount = $cartItems->sum(function($item) {
                return $item->price * $item->quantity;
            });
            
            // Generate kode transaksi
            $transactionCode = 'TRX-' . date('Ymd') . '-' . strtoupper(uniqid());

            // Final amount sama dengan total amount karena tidak ada tax dan service charge
            $finalAmount = $totalAmount;

            // Buat reservasi
            $reservasi = Reservasi::create([
                'meja_id' => $meja->id,
                'user_id' => auth()->id(),
                'date' => $validated['tanggal'],
                'start_time' => $validated['jam'],
                'end_time' => Carbon::parse($validated['jam'])->addHours($validated['durasi'])->format('H:i'),
                'status' => 'pending'
            ]);

            Log::info('Created Reservasi:', $reservasi->toArray());

            // Buat transaksi
            $transaksi = Transaksi::create([
                'transaction_code' => $transactionCode,
                'user_id' => auth()->id(),
                'reservasi_id' => $reservasi->id,
                'total_amount' => $totalAmount,
                'final_amount' => $finalAmount,
                'status' => 'pending',
                'payment_method' => $validated['payment_method']
            ]);

            Log::info('Created Transaksi:', $transaksi->toArray());

            // Simpan item transaksi
            foreach ($cartItems as $item) {
                $transaksiItem = TransaksiItem::create([
                    'transaksi_id' => $transaksi->id,
                    'menu_id' => $item->menu_id,
                    'menu_name' => $item->menu->name,
                    'quantity' => $item->quantity,
                    'price' => $item->price,
                    'subtotal' => $item->subtotal
                ]);
                Log::info('Created TransaksiItem:', $transaksiItem->toArray());
            }

            // Update status meja
            $meja->status = 'dipesan';
            $meja->save();

            // Hapus cart items
            Cart::where('user_id', auth()->id())->delete();

            DB::commit();

            return redirect()->route('transaksi.show', $transaksi->id)
                ->with('success', 'Reservasi berhasil dibuat, silahkan lakukan pembayaran');

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Transaksi Error:', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return back()->with('error', 'Terjadi kesalahan saat memproses transaksi: ' . $e->getMessage());
        }
    }

    // Konfirmasi pembayaran
    public function confirm(Request $request, $id)
    {
        DB::beginTransaction();
        try {
            $transaksi = Transaksi::with('reservasi')->findOrFail($id);
            
            // Pastikan transaksi milik user yang sedang login
            if ($transaksi->user_id !== auth()->id()) {
                throw new \Exception('Unauthorized access');
            }
            
            // Pastikan status transaksi masih pending
            if ($transaksi->status !== 'pending') {
                throw new \Exception('Transaksi sudah tidak dapat diproses');
            }

            // Update status transaksi
            $transaksi->status = 'paid';
            $transaksi->paid_at = now();
            $transaksi->save();

            // Update status reservasi
            if ($transaksi->reservasi) {
                $transaksi->reservasi->status = 'confirmed';
                $transaksi->reservasi->save();
            }

            DB::commit();

            return redirect()->route('transaksi.show', $id)
                ->with('success', 'Pembayaran berhasil dikonfirmasi');

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error in payment confirmation: ' . $e->getMessage());
            return back()->with('error', 'Terjadi kesalahan saat mengkonfirmasi pembayaran: ' . $e->getMessage());
        }
    }

    // Callback untuk Midtrans notification
    public function notification(Request $request)
    {
        try {
            $midtransService = new \App\Services\MidtransService();
            $notificationData = $midtransService->handleNotification();
            
            Log::info('Processing Midtrans notification', $notificationData);

            // Handle order_id with modal suffix
            $originalOrderId = preg_replace('/-modal-\d+$/', '', $notificationData['order_id']);
            
            DB::beginTransaction();

            $transaksi = Transaksi::where('transaction_code', $originalOrderId)->firstOrFail();
            $reservasi = $transaksi->reservasi;

            // Get current status to check if we need to update
            $currentStatus = $transaksi->status;
            $newStatus = null;

            switch ($notificationData['transaction_status']) {
                case 'capture':
                    if ($notificationData['payment_type'] == 'credit_card') {
                        if ($notificationData['fraud_status'] == 'challenge') {
                            $newStatus = 'pending';
                        } else {
                            $newStatus = 'paid';
                        }
                    }
                    break;
                case 'settlement':
                    $newStatus = 'paid';
                    break;
                case 'pending':
                    $newStatus = 'pending';
                    break;
                case 'deny':
                case 'expire':
                case 'cancel':
                    $newStatus = 'cancelled';
                    break;
            }

            // Only update if status has changed
            if ($newStatus && $currentStatus !== $newStatus) {
                Log::info("Updating transaction status from {$currentStatus} to {$newStatus}", [
                    'transaction_code' => $transaksi->transaction_code
                ]);

                $transaksi->status = $newStatus;
                
                if ($newStatus === 'paid') {
                    $transaksi->paid_at = now();
                    
                    if ($reservasi) {
                        $reservasi->status = 'confirmed';
                        $reservasi->save();
                    }
                } elseif ($newStatus === 'cancelled') {
                    if ($reservasi) {
                        $reservasi->status = 'cancelled';
                        $reservasi->save();
                    }
                }

                $transaksi->save();
            }

            DB::commit();
            
            return response()->json(['status' => 'success']);

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error processing Midtrans notification: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            return response()->json([
                'status' => 'error',
                'message' => 'An error occurred while processing the payment notification'
            ], 500);
        }
    }

    // Add new method to check payment status
    public function checkStatus($id)
    {
        try {
            $transaksi = Transaksi::findOrFail($id);
            return response()->json([
                'status' => $transaksi->status,
                'paid_at' => $transaksi->paid_at ? $transaksi->paid_at->format('Y-m-d H:i:s') : null
            ]);
        } catch (\Exception $e) {
            Log::error('Error checking payment status: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to check payment status'], 500);
        }
    }

    // Halaman sukses setelah pembayaran
    public function finish(Request $request)
    {
        try {
            $order_id = $request->order_id;
            $transaksi = Transaksi::where('transaction_code', $order_id)->firstOrFail();
            
            return redirect()->route('transaksi.show', $transaksi->id)
                ->with('success', 'Pembayaran berhasil diproses');
        } catch (\Exception $e) {
            Log::error('Payment Finish Error: ' . $e->getMessage());
            return redirect()->route('transaksi.index')
                ->with('error', 'Terjadi kesalahan saat memproses pembayaran');
        }
    }

    // Halaman saat pembayaran tidak berhasil
    public function unfinish(Request $request)
    {
        try {
            $order_id = $request->order_id;
            $transaksi = Transaksi::where('transaction_code', $order_id)->firstOrFail();
            
            return redirect()->route('transaksi.show', $transaksi->id)
                ->with('error', 'Pembayaran belum selesai');
        } catch (\Exception $e) {
            Log::error('Payment Unfinish Error: ' . $e->getMessage());
            return redirect()->route('transaksi.index')
                ->with('error', 'Terjadi kesalahan saat memproses pembayaran');
        }
    }

    // Halaman saat pembayaran error
    public function error(Request $request)
    {
        return redirect()->route('transaksi.index')
            ->with('error', 'Terjadi kesalahan dalam proses pembayaran');
    }

    // Menampilkan detail transaksi untuk modal
    public function detail($id)
    {
        try {
            // Find the transaction with its relationships and get fresh data
            $transaksi = Transaksi::with(['reservasi.meja', 'items.menu', 'user'])
                ->where('user_id', auth()->id())
                ->findOrFail($id);
            
            // Refresh the model to get the latest status
            $transaksi->refresh();
            
            if (!$transaksi) {
                throw new \Exception('Transaksi tidak ditemukan');
            }

            $reservasi = $transaksi->reservasi;
            if (!$reservasi) {
                throw new \Exception('Data reservasi tidak ditemukan');
            }

            $items = $transaksi->items;

            // Get Midtrans snap token if payment is pending
            $snapToken = null;
            if ($transaksi->status === 'pending') {
                try {
                    $midtransService = new \App\Services\MidtransService();
                    // Add modal suffix to create a unique order ID
                    $originalCode = $transaksi->transaction_code;
                    $transaksi->transaction_code = $originalCode . '-modal-' . time();
                    $snapToken = $midtransService->createTransaction($transaksi);
                    // Restore original transaction code
                    $transaksi->transaction_code = $originalCode;
                } catch (\Exception $e) {
                    Log::error('Error creating Midtrans token for modal: ' . $e->getMessage());
                    // Continue without snap token
                }
            }
            
            return view('transaksi.detail', compact('transaksi', 'reservasi', 'items', 'snapToken'));
        } catch (\Exception $e) {
            return response()->json([
                'error' => 'Terjadi kesalahan saat menampilkan transaksi: ' . $e->getMessage()
            ], 500);
        }
    }

    public function cancel(Transaksi $transaksi)
    {
        try {
            // Check if transaction can be cancelled
            if ($transaksi->status !== 'pending') {
                return redirect()->back()->with('error', 'Hanya transaksi dengan status pending yang dapat dibatalkan.');
            }

            DB::beginTransaction();

            // Update transaction status
            $transaksi->update([
                'status' => 'cancelled'
            ]);

            // Update reservation status
            if ($transaksi->reservasi) {
                $transaksi->reservasi->update([
                    'status' => 'cancelled'
                ]);

                // Update table status if the reservation is for today
                if ($transaksi->reservasi->date == now()->format('Y-m-d')) {
                    $transaksi->reservasi->meja()->update([
                        'status' => 'tersedia'
                    ]);
                }
            }

            DB::commit();

            return redirect()->route('transaksi.show', $transaksi->id)
                ->with('success', 'Pesanan berhasil dibatalkan.');

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error cancelling transaction: ' . $e->getMessage());
            
            return redirect()->back()
                ->with('error', 'Terjadi kesalahan saat membatalkan pesanan. Silakan coba lagi.');
        }
    }
}
