<?php

namespace App\Http\Controllers\Console;

use App\Http\Controllers\Controller;
use App\Models\Reservation;
use App\Models\Outlet;
use App\Models\Table;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;

/**
 * ReservationController - MVP Implementation
 * 
 * Handles table reservation management for cashier/admin.
 * 
 * TODO ENHANCEMENTS:
 * - Add email notifications (confirmation, reminder, cancellation)
 * - Add capacity validation (prevent double booking)
 * - Add time slot management
 * - Add calendar view
 * - Add customer-facing reservation form
 * - Add conflict detection (check if table already reserved for time slot)
 * - Add automatic status update (no-show if customer doesn't arrive)
 */
class ReservationController extends Controller
{
    /**
     * Display a listing of reservations.
     */
    public function index(Request $request)
    {
        $query = Reservation::with(['user', 'outlet', 'table'])
            ->orderBy('reservation_date', 'desc')
            ->orderBy('reservation_time', 'desc');

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // Filter by outlet
        if ($request->filled('outlet_id')) {
            $query->where('outlet_id', $request->outlet_id);
        }

        // Filter by date
        if ($request->filled('date')) {
            $query->whereDate('reservation_date', $request->date);
        }

        $reservations = $query->paginate(15);

        // Get statistics
        $stats = [
            'total_reservations' => Reservation::count(),
            'pending_reservations' => Reservation::where('status', Reservation::STATUS_PENDING)->count(),
            'confirmed_reservations' => Reservation::where('status', Reservation::STATUS_CONFIRMED)->count(),
            'today_reservations' => Reservation::today()->count(),
            'upcoming_reservations' => Reservation::upcoming()->count(),
        ];

        $statuses = Reservation::getStatuses();
        $outlets = Outlet::all();

        return view('console.reservations.index', compact(
            'reservations',
            'stats',
            'statuses',
            'outlets'
        ));
    }

    /**
     * Show the form for creating a new reservation.
     */
    public function create()
    {
        $outlets = Outlet::all();
        $tables = Table::where('status', 'available')->get();
        
        return view('console.reservations.create', compact('outlets', 'tables'));
    }

    /**
     * Store a newly created reservation in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'outlet_id' => 'required|exists:outlets,id',
            'table_id' => 'nullable|exists:tables,id',
            'reservation_date' => 'required|date|after_or_equal:today',
            'reservation_time' => 'required|date_format:H:i',
            'party_size' => 'required|integer|min:1|max:20',
            'guest_name' => 'required|string|max:255',
            'guest_email' => 'required|email|max:255',
            'guest_phone' => 'required|string|max:20',
            'special_requests' => 'nullable|string|max:500',
            'notes' => 'nullable|string|max:500',
        ]);

        // Generate unique reservation number
        $reservationNumber = 'RSV-' . Str::upper(Str::random(8));
        while (Reservation::where('reservation_number', $reservationNumber)->exists()) {
            $reservationNumber = 'RSV-' . Str::upper(Str::random(8));
        }

        // TODO: Add conflict detection here
        // Check if table is already reserved for this time slot

        $reservation = Reservation::create([
            'reservation_number' => $reservationNumber,
            'user_id' => null, // For now, all reservations created by cashier are guest reservations
            'guest_info' => [
                'name' => $validated['guest_name'],
                'email' => $validated['guest_email'],
                'phone' => $validated['guest_phone'],
            ],
            'outlet_id' => $validated['outlet_id'],
            'table_id' => $validated['table_id'],
            'reservation_date' => $validated['reservation_date'],
            'reservation_time' => $validated['reservation_time'],
            'party_size' => $validated['party_size'],
            'status' => Reservation::STATUS_CONFIRMED, // Auto-confirm if created by cashier
            'special_requests' => $validated['special_requests'],
            'notes' => $validated['notes'],
            'confirmed_at' => now(),
        ]);

        Log::info('Reservation created by cashier', [
            'reservation_number' => $reservation->reservation_number,
            'cashier' => auth()->user()->name,
        ]);

        // TODO: Send confirmation email to customer

        return redirect()->route('reservations.index')
            ->with('success', 'Reservasi berhasil dibuat dengan nomor: ' . $reservation->reservation_number);
    }

    /**
     * Display the specified reservation.
     */
    public function show(Reservation $reservation)
    {
        $reservation->load(['user', 'outlet', 'table']);
        
        return view('console.reservations.show', compact('reservation'));
    }

    /**
     * Show the form for editing the specified reservation.
     */
    public function edit(Reservation $reservation)
    {
        $outlets = Outlet::all();
        $tables = Table::all();
        
        return view('console.reservations.edit', compact('reservation', 'outlets', 'tables'));
    }

    /**
     * Update the specified reservation in storage.
     */
    public function update(Request $request, Reservation $reservation)
    {
        $validated = $request->validate([
            'outlet_id' => 'required|exists:outlets,id',
            'table_id' => 'nullable|exists:tables,id',
            'reservation_date' => 'required|date',
            'reservation_time' => 'required|date_format:H:i',
            'party_size' => 'required|integer|min:1|max:20',
            'status' => 'required|in:' . implode(',', array_keys(Reservation::getStatuses())),
            'special_requests' => 'nullable|string|max:500',
            'notes' => 'nullable|string|max:500',
        ]);

        $reservation->update($validated);

        // Update timestamps based on status change
        if ($validated['status'] === Reservation::STATUS_CONFIRMED && !$reservation->confirmed_at) {
            $reservation->update(['confirmed_at' => now()]);
        }
        if ($validated['status'] === Reservation::STATUS_CANCELLED && !$reservation->cancelled_at) {
            $reservation->update(['cancelled_at' => now()]);
        }

        Log::info('Reservation updated', [
            'reservation_number' => $reservation->reservation_number,
            'updated_by' => auth()->user()->name,
        ]);

        return redirect()->route('reservations.show', $reservation)
            ->with('success', 'Reservasi berhasil diperbarui.');
    }

    /**
     * Remove the specified reservation from storage.
     */
    public function destroy(Reservation $reservation)
    {
        // Soft delete - just mark as cancelled instead of deleting
        $reservation->update([
            'status' => Reservation::STATUS_CANCELLED,
            'cancelled_at' => now(),
        ]);

        Log::info('Reservation cancelled', [
            'reservation_number' => $reservation->reservation_number,
            'cancelled_by' => auth()->user()->name,
        ]);

        return redirect()->route('reservations.index')
            ->with('success', 'Reservasi berhasil dibatalkan.');
    }

    /**
     * Update reservation status
     */
    public function updateStatus(Request $request, Reservation $reservation)
    {
        $validated = $request->validate([
            'status' => 'required|in:' . implode(',', array_keys(Reservation::getStatuses()))
        ]);

        $oldStatus = $reservation->status;
        $newStatus = $validated['status'];

        $reservation->update(['status' => $newStatus]);

        // Update timestamps
        if ($newStatus === Reservation::STATUS_CONFIRMED && !$reservation->confirmed_at) {
            $reservation->update(['confirmed_at' => now()]);
        }
        if ($newStatus === Reservation::STATUS_CANCELLED && !$reservation->cancelled_at) {
            $reservation->update(['cancelled_at' => now()]);
        }

        Log::info('Reservation status updated', [
            'reservation_number' => $reservation->reservation_number,
            'old_status' => $oldStatus,
            'new_status' => $newStatus,
            'updated_by' => auth()->user()->name,
        ]);

        // TODO: Send notification to customer

        return response()->json([
            'success' => true,
            'message' => 'Status reservasi berhasil diperbarui.',
            'reservation' => $reservation->fresh(),
        ]);
    }
}
