<?php

namespace App\Http\Controllers;

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

class ReservasiController extends Controller
{
    // Tampilkan formulir reservasi
    public function index()
    {
        try {
            $mejaId = session('selected_meja');
            $meja = $mejaId ? Meja::findOrFail($mejaId) : null;
            
            $cartItems = auth()->check() ? Cart::where('user_id', auth()->id())->with('menu')->get() : collect();
            
            $totals = [
                'subtotal' => 0
            ];
            
            if ($cartItems->count() > 0) {
                $subtotal = $cartItems->sum(function ($item) {
                    return $item->quantity * $item->menu->price;
                });
                
                $totals = [
                    'subtotal' => $subtotal
                ];
            }
            
            return view('reservasi', compact('meja', 'cartItems', 'totals'));
        } catch (\Exception $e) {
            Log::error('Error in ReservasiController@index: ' . $e->getMessage());
            return redirect()->route('menu.index')->with('error', 'Terjadi kesalahan. Silakan coba lagi.');
        }
    }

    // Simpan data reservasi
    public function store(Request $request)
    {
        DB::beginTransaction();
        try {
            // Validasi input
            $request->validate([
                'tanggal' => 'required|date|after_or_equal:today',
                'start_time' => 'required'
            ]);

            $mejaId = session('selected_meja');
            if (!$mejaId) {
                throw new \Exception('Silakan pilih meja terlebih dahulu');
            }

            // Cek ketersediaan meja
            $meja = Meja::findOrFail($mejaId);
            if ($meja->status === 'tidak_tersedia') {
                throw new \Exception('Meja tidak tersedia');
            }

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

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

            // Hitung total harga
            $totalHarga = $cartItems->sum(function($item) {
                return $item->quantity * $item->menu->price;
            });

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

            // Buat reservasi
            $reservasi = Reservasi::create([
                'meja_id' => $mejaId,
                'user_id' => auth()->id(),
                'date' => $request->tanggal,
                'start_time' => $request->start_time,
                'status' => 'pending',
                'name' => auth()->user()->name,
                'phone' => auth()->user()->phone ?? '',
                'total_harga' => $totalHarga
            ]);

            // Generate kode transaksi
            $transactionCode = 'TRX-' . date('Ymd') . '-' . strtoupper(uniqid());

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

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

            // Update status meja jika reservasi untuk hari ini
            if ($request->tanggal === date('Y-m-d')) {
                $meja->status = 'dipesan';
                $meja->save();
            }

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

            // Clear session meja
            session()->forget('selected_meja');

            DB::commit();

            // Redirect ke halaman detail transaksi
            return redirect()->route('transaksi.detail', $transaksi->id)
                ->with('success', 'Reservasi berhasil dibuat, silakan lakukan pembayaran');

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Error creating reservation and transaction: ' . $e->getMessage());
            return back()->with('error', 'Terjadi kesalahan saat membuat reservasi: ' . $e->getMessage());
        }
    }

    public function success($id)
    {
        $reservasi = Reservasi::with('meja')->findOrFail($id);
        return view('reservasi.success', compact('reservasi'));
    }

    public function checkAvailability(Request $request)
    {
        $request->validate([
            'tanggal' => 'required|date',
            'meja_id' => 'required|exists:mejas,id'
        ]);

        $reservasi = Reservasi::where('meja_id', $request->meja_id)
            ->where('tanggal', $request->tanggal)
            ->get();

        $bookedHours = [];
        foreach ($reservasi as $r) {
            $startTime = Carbon::parse($r->jam);
            for ($i = 0; $i < $r->durasi; $i++) {
                $bookedHours[] = $startTime->copy()->addHours($i)->format('H:i');
            }
        }

        $availableHours = [];
        $start = Carbon::parse('10:00');
        $end = Carbon::parse('22:00');

        while ($start <= $end) {
            if (!in_array($start->format('H:i'), $bookedHours)) {
                $availableHours[] = $start->format('H:i');
            }
            $start->addHour();
        }

        return response()->json($availableHours);
    }

    public function getSchedule(Request $request, Meja $meja)
    {
        $date = $request->date;
        
        $reservations = Reservasi::where('meja_id', $meja->id)
            ->where('date', $date)
            ->where('status', '!=', 'cancelled')
            ->get(['start_time', 'end_time']);

        return response()->json([
            'success' => true,
            'reservations' => $reservations
        ]);
    }

    public function getAvailableSlots(Request $request)
    {
        try {
            $date = $request->date;
            $mejaId = session('selected_meja');
            
            if (!$date || !$mejaId) {
                return response()->json([
                    'status' => 'error',
                    'error' => 'Data tidak lengkap'
                ], 400);
            }

            $meja = Meja::findOrFail($mejaId);
            $availableSlots = $meja->getAvailableTimeSlots($date);

            // Jika tanggal hari ini, filter slot yang sudah lewat
            if ($date === date('Y-m-d')) {
                $currentTime = Carbon::now();
                $availableSlots = array_filter($availableSlots, function($slot) use ($currentTime) {
                    return Carbon::parse($slot)->gt($currentTime);
                });
            }

            return response()->json([
                'status' => 'success',
                'data' => array_values($availableSlots)
            ]);

        } catch (\Exception $e) {
            Log::error('Error in getAvailableSlots: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'error' => 'Terjadi kesalahan saat memuat slot waktu'
            ], 500);
        }
    }

    /**
     * Handle Midtrans payment notification
     */
    public function handlePaymentNotification(Request $request)
    {
        try {
            $notification = json_decode($request->getContent(), true);
            
            // Get transaction
            $transaction = Transaksi::where('transaction_code', $notification['order_id'])->firstOrFail();
            $reservasi = $transaction->reservasi;

            // Update payment method based on Midtrans payment type
            $paymentType = $notification['payment_type'];
            switch ($paymentType) {
                case 'credit_card':
                    $paymentMethod = 'credit_card';
                    break;
                case 'bank_transfer':
                    $vaNumbers = $notification['va_numbers'][0] ?? null;
                    if ($vaNumbers) {
                        $bank = strtolower($vaNumbers['bank']);
                        $paymentMethod = $bank . '_va';
                    } else {
                        $paymentMethod = 'other_va';
                    }
                    break;
                case 'gopay':
                    $paymentMethod = 'gopay';
                    break;
                case 'shopeepay':
                    $paymentMethod = 'shopeepay';
                    break;
                case 'qris':
                    $paymentMethod = 'qris';
                    break;
                case 'cstore':
                    $store = strtolower($notification['store']);
                    $paymentMethod = $store;
                    break;
                default:
                    $paymentMethod = $paymentType;
            }

            // Update reservation payment method
            $reservasi->update([
                'payment_method' => $paymentMethod
            ]);

            // Handle transaction status
            if ($notification['transaction_status'] == 'capture' || $notification['transaction_status'] == 'settlement') {
                $transaction->update(['status' => 'paid']);
                $reservasi->update(['status' => 'confirmed']);
            } elseif ($notification['transaction_status'] == 'cancel' || $notification['transaction_status'] == 'deny' || $notification['transaction_status'] == 'expire') {
                $transaction->update(['status' => 'cancelled']);
                $reservasi->update(['status' => 'cancelled']);
            }

            return response()->json(['status' => 'success']);
        } catch (\Exception $e) {
            Log::error('Error handling Midtrans notification: ' . $e->getMessage());
            return response()->json(['status' => 'error'], 500);
        }
    }
}
