<?php

namespace App\Http\Controllers\Admin;

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

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

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

        // Build nice labels (Europe/London) 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('bookings.create', [
            'slot'        => $slot,
            'date'        => $data['date'],
            'prettyDate'  => $prettyDate,
            'prettyTime'  => $prettyTime,
            'weekdayName' => $weekdayName,
        ]);
    }
	
	public function store(\Illuminate\Http\Request $request)
	{
		// Needed at top of file (ensure these use's exist):
		// 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'],
			'student_name'     => ['required','string','max:255'],
			'booked_from_page' => ['nullable','string','max:255'],
			'message'          => ['nullable','string'],
		]);

		// Enforce > 2 hours' notice (exactly 120 mins = NOT allowed)
		$slot = \App\Models\Slot::findOrFail($data['slot_id']);
		$sessionStart = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', "{$data['date']} {$slot->time}", 'Europe/London');
		$now = \Carbon\Carbon::now('Europe/London');
		$minutesUntil = $now->diffInMinutes($sessionStart, false);

		if ($minutesUntil <= 120) {
			throw \Illuminate\Validation\ValidationException::withMessages([
				'date' => 'Bookings require more than 2 hours’ notice.',
			]);
		}

		// Persist booking; default status for admin-created bookings = 'booked'
		$data['status'] = 'booked';

		try {
			\App\Models\Booking::create($data);
		} catch (\Illuminate\Database\QueryException $e) {
			// Handle unique (slot_id, date) violation gracefully
			if (isset($e->errorInfo[1]) && (int)$e->errorInfo[1] === 1062) {
				throw \Illuminate\Validation\ValidationException::withMessages([
					'slot_id' => 'That slot has just been taken. Please choose another.',
				]);
			}
			throw $e;
		}

		return redirect()
			->route('admin.calendar')
			->with('success', 'Booking created successfully.');
	}	
	
	public function createBlock(\Illuminate\Http\Request $request)
	{
		// Needed at top of file:
		// use App\Models\Slot;
		// use Carbon\Carbon;

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

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

		// Prettify for the view (no Carbon in Blade)
		$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');

		return view('bookings.block', [
			'slot'        => $slot,
			'date'        => $data['date'],
			'prettyDate'  => $prettyDate,
			'prettyTime'  => $prettyTime,
			'weekdayName' => $weekdayName,
		]);
	}	

	public function storeBlock(\Illuminate\Http\Request $request)
	{
		// Validation: block a specific slot on a specific date
		$data = $request->validate([
			'slot_id' => ['required','exists:slots,id'],
			'date'    => ['required','date_format:Y-m-d'],
			'message' => ['nullable','string'], // optional reason/notes for the block
		]);

		// Create a "blocked" booking for that slot/date
		try {
			\App\Models\Booking::create([
				'slot_id'          => (int)$data['slot_id'],
				'date'             => $data['date'],
				'student_name'     => null,            // blocks don't need a student
				'booked_from_page' => 'admin:block',   // provenance
				'message'          => $data['message'] ?? null,
				'status'           => 'blocked',
			]);
		} catch (\Illuminate\Database\QueryException $e) {
			// Unique (slot_id, date) hit — something already exists for that slot/date
			if (isset($e->errorInfo[1]) && (int)$e->errorInfo[1] === 1062) {
				return back()
					->withErrors(['slot_id' => 'That slot/date already has a booking or block.'])
					->withInput();
			}
			throw $e;
		}

		return redirect()
			->route('admin.calendar')
			->with('success', 'Slot blocked successfully.');
	}
	
	public function createSeries(\Illuminate\Http\Request $request)
	{
		// Needed at top of file (ensure these exist):
		// use App\Models\Slot;
		// use Carbon\Carbon;

		// Accept prefill from calendar click: ?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']);

		// Precompute nice 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; // sensible default

		return view('bookings.series', [
			'slot'        => $slot,
			'date'        => $data['date'],
			'prettyDate'  => $prettyDate,
			'prettyTime'  => $prettyTime,
			'weekdayName' => $weekdayName,
			'weeks'       => $weeks,
		]);
	}

	public function storeSeries(\Illuminate\Http\Request $request)
	{
		// Needed at top of file:
		// use App\Models\Slot;
		// use App\Models\Booking;
		// use Carbon\Carbon;
		// use Illuminate\Database\QueryException;

		$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');

		$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');

			// Skip past or ≤ 2 hours from now
			$minutesUntil = $now->diffInMinutes($sessionStart, false);
			if ($minutesUntil <= 120) {
				$skipped++;
				continue;
			}

			try {
				\App\Models\Booking::create([
					'slot_id'          => $slot->id,
					'date'             => $date,
					'student_name'     => null,                     // series = no student name
					'booked_from_page' => 'admin:block-series',     // provenance
					'message'          => null,
					'status'           => 'booked',                 // shows as “Booked” on the calendar
				]);
				$created++;
			} catch (\Illuminate\Database\QueryException $e) {
				// Skip duplicates (unique (slot_id, date) might already exist as booked/closed)
				if (isset($e->errorInfo[1]) && (int)$e->errorInfo[1] === 1062) {
					$skipped++;
					continue;
				}
				throw $e;
			}
		}

		// Redirect back to the week containing the start date (nice UX)
		$displayStart = $now->copy()->startOfWeek(\Carbon\Carbon::MONDAY);
		$fridayCutoff = $displayStart->copy()->addDays(4)->setTime(15, 0);
		if ($now->greaterThanOrEqualTo($fridayCutoff)) {
			$displayStart->addWeek();
		}
		$weekOffset = $displayStart->diffInWeeks($startDate->copy()->startOfWeek(\Carbon\Carbon::MONDAY), false);

		return redirect()
			->route('admin.calendar', ['week' => $weekOffset ?: null])
			->with('success', "Series created: {$created} added, {$skipped} skipped.");
	}

}
