<?php

namespace App\Http\Controllers\Student;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Slot;
use Carbon\Carbon;
use App\Services\AvailabilityService;

class BookingController extends Controller
{
    public function create(Request $request)
    {
        // Expect: /student/bookings/create?date=YYYY-MM-DD&slot_id=NN
        $data = $request->validate([
            'date'    => ['required','date_format:Y-m-d'],
            'slot_id' => ['required','exists:slots,id'],
        ]);

        $slot = Slot::findOrFail($data['slot_id']);

        // Prettify labels so Blade doesn’t need Carbon
        $when = Carbon::createFromFormat('Y-m-d H:i:s', "{$data['date']} {$slot->time}", 'Europe/London');
        $prettyDate  = $when->format('D d M Y');
        $prettyTime  = $when->format('H:i');
        $weekdayName = $when->format('l');

        return view('student.bookings.create', [
            'slot'        => $slot,
            'date'        => $data['date'],
            'prettyDate'  => $prettyDate,
            'prettyTime'  => $prettyTime,
            'weekdayName' => $weekdayName,
        ]);
    }	
	
	public function createSeries(\Illuminate\Http\Request $request)
	{
		// Ensure these use's exist at the top of the file:
		// use App\Models\Slot;
		// use Carbon\Carbon;

		// Expect: /student/bookings/series/create?date=YYYY-MM-DD&slot_id=NN&weeks=6
		$data = $request->validate([
			'date'    => ['required','date_format:Y-m-d'],
			'slot_id' => ['required','exists:slots,id'],
			'weeks'   => ['nullable','integer','min:1','max:52'],
		]);

		$slot = \App\Models\Slot::findOrFail($data['slot_id']);

		// Prettify labels (keep Blade Carbon-free)
		$when = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', "{$data['date']} {$slot->time}", 'Europe/London');
		$prettyDate  = $when->format('D d M Y');
		$prettyTime  = $when->format('H:i');
		$weekdayName = $when->format('l');

		$weeks = $data['weeks'] ?? 6;

		return view('student.bookings.series', [
			'slot'        => $slot,
			'date'        => $data['date'],
			'prettyDate'  => $prettyDate,
			'prettyTime'  => $prettyTime,
			'weekdayName' => $weekdayName,
			'weeks'       => $weeks,
		]);
	}	
	
	public function store(\Illuminate\Http\Request $request)
	{
		// Ensure these use's exist at the top of the file:
		// use App\Models\Slot;
		// use App\Models\Booking;
		// use Carbon\Carbon;
		// use Illuminate\Validation\ValidationException;
		// use Illuminate\Database\QueryException;

		$data = $request->validate([
			'slot_id' => ['required','exists:slots,id'],
			'date'    => ['required','date_format:Y-m-d'],
			'message' => ['nullable','string'],
		]);

		$slot = \App\Models\Slot::findOrFail($data['slot_id']);

		// Enforce > 2 hours’ notice (exactly 120 mins = NOT allowed)
		$now = \Carbon\Carbon::now('Europe/London');
		$sessionStart = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', "{$data['date']} {$slot->time}", 'Europe/London');
		$minutesUntil = $now->diffInMinutes($sessionStart, false);
		if ($minutesUntil <= 120) {
			throw \Illuminate\Validation\ValidationException::withMessages([
				'date' => 'Bookings require more than 2 hours’ notice.',
			]);
		}

		// Pull student name from the logged-in user
		$user = $request->user();
		$studentName = $user?->name ?? 'Student';

		try {
			\App\Models\Booking::create([
				'slot_id'          => $slot->id,
				'date'             => $data['date'],
				'student_name'     => $studentName,
				'booked_from_page' => 'student:booking',
				'message'          => $data['message'] ?? null,
				'status'           => 'booked',
			]);
		} catch (\Illuminate\Database\QueryException $e) {
			// Unique (slot_id, date) hit — slot already taken
			if (isset($e->errorInfo[1]) && (int)$e->errorInfo[1] === 1062) {
				throw \Illuminate\Validation\ValidationException::withMessages([
					'slot_id' => 'Sorry, that slot was just taken. Please choose another.',
				]);
			}
			throw $e;
		}

		return redirect()
			->route('student.calendar')
			->with('success', 'Your booking is confirmed.');
	}
	
	public function storeSeries(\Illuminate\Http\Request $request)
	{
		// Validates: slot, start date, and weeks count
		$data = $request->validate([
			'slot_id' => ['required','exists:slots,id'],
			'date'    => ['required','date_format:Y-m-d'], // start date
			'weeks'   => ['required','integer','min:1','max:52'],
		]);

		$slot      = \App\Models\Slot::findOrFail($data['slot_id']);
		$now       = \Carbon\Carbon::now('Europe/London');
		$startDate = \Carbon\Carbon::createFromFormat('Y-m-d', $data['date'], 'Europe/London');
		$user      = $request->user();
		$student   = $user?->name ?? 'Student';

		$created = 0;
		$skipped = 0;

		for ($i = 0; $i < (int)$data['weeks']; $i++) {
			$date = $startDate->copy()->addWeeks($i)->toDateString();
			$sessionStart = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', "{$date} {$slot->time}", 'Europe/London');

			// Enforce > 2 hours’ notice (exactly 120 mins = NOT allowed)
			$minutesUntil = $now->diffInMinutes($sessionStart, false);
			if ($minutesUntil <= 120) {
				$skipped++;
				continue;
			}

			try {
				\App\Models\Booking::create([
					'slot_id'          => $slot->id,
					'date'             => $date,
					'student_name'     => $student,
					'booked_from_page' => 'student:block-series',
					'message'          => null,
					'status'           => 'booked',
				]);
				$created++;
			} catch (\Illuminate\Database\QueryException $e) {
				// Skip duplicates (unique (slot_id, date))
				if (isset($e->errorInfo[1]) && (int)$e->errorInfo[1] === 1062) {
					$skipped++;
					continue;
				}
				throw $e;
			}
		}

		return redirect()
			->route('student.calendar')
			->with('success', "Series created: {$created} added, {$skipped} skipped.");
	}
	
	public function cancelConfirm(\App\Models\Booking $booking)
	{
		// Ensure these use's exist at the top:
		// use App\Models\Booking;
		// use Carbon\Carbon;

		$user = auth()->user();
		$studentName = $user?->name ?? '';

		// Authorize: must be this student's booking and still "booked"
		if ($booking->student_name !== $studentName || $booking->status !== 'booked') {
			abort(403);
		}

		// Need the slot's time to compute the session start
		$booking->load('slot');

		$now = \Carbon\Carbon::now('Europe/London');
		$sessionStart = \Carbon\Carbon::createFromFormat(
			'Y-m-d H:i:s',
			$booking->date.' '.$booking->slot->time,
			'Europe/London'
		);

		$minutesUntil = $now->diffInMinutes($sessionStart, false);

		// If already started or in the past, disallow cancellation
		if ($minutesUntil <= 0) {
			return redirect()
				->route('student.bookings.index')
				->withErrors(['booking' => 'This session has started or is in the past and can’t be cancelled.']);
		}

		// Refund policy band (for display only; payments added later)
		// ≥ 24h => 100%; < 24h => 50%
		$refundPercent = ($minutesUntil >= 24 * 60) ? 100 : 50;

		// Prettified labels so Blade stays Carbon-free
		$prettyDate  = $sessionStart->format('D d M Y');
		$prettyTime  = $sessionStart->format('H:i');
		$weekdayName = $sessionStart->format('l');

		return view('student.bookings.cancel', [
			'booking'       => $booking,
			'prettyDate'    => $prettyDate,
			'prettyTime'    => $prettyTime,
			'weekdayName'   => $weekdayName,
			'refundPercent' => $refundPercent,
			'minutesUntil'  => $minutesUntil,
		]);
	}
	
	public function cancelStore(\App\Models\Booking $booking)
	{
		// Ensure these use's exist at the top:
		// use App\Models\Booking;
		// use Carbon\Carbon;

		$user = auth()->user();
		$studentName = $user?->name ?? '';

		// Authorize: must be this student's booking and still "booked"
		if ($booking->student_name !== $studentName || $booking->status !== 'booked') {
			abort(403);
		}

		// Need slot time to compute the session start
		$booking->load('slot');

		$now = \Carbon\Carbon::now('Europe/London');
		$sessionStart = \Carbon\Carbon::createFromFormat(
			'Y-m-d H:i:s',
			$booking->date.' '.$booking->slot->time,
			'Europe/London'
		);

		$minutesUntil = $now->diffInMinutes($sessionStart, false);

		// If already started or in the past, disallow cancellation
		if ($minutesUntil <= 0) {
			return redirect()
				->route('student.bookings.index')
				->withErrors(['booking' => 'This session has started or is in the past and can’t be cancelled.']);
		}

		// Refund band (for info only; payments to be integrated later)
		$refundPercent = ($minutesUntil >= 24 * 60) ? 100 : 50;

		// For now, delete the booking to free the slot.
		// (Later we can switch to a "cancelled" status or soft deletes if you want a history.)
		$booking->delete();

		return redirect()
			->route('student.bookings.index')
			->with('success', "Booking cancelled. Refund: {$refundPercent}%.");
	}
}
