<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * Bookings, the halls attached to each booking, and the hall availability
 * calendar that enforces double-booking prevention at the database layer
 * via a unique index on (hall_id, date, slot).
 *
 * Tentative holds carry an expiry; a scheduled job releases stale holds.
 */
return new class extends Migration {
    public function up(): void
    {
        if (! Schema::hasTable('bms_bookings')) {
            Schema::create('bms_bookings', function (Blueprint $t) {
                $t->bigIncrements('id');
                $t->unsignedInteger('business_id');
                $t->string('booking_no', 40)->nullable();
                $t->unsignedInteger('contact_id')->nullable();
                $t->unsignedBigInteger('lead_id')->nullable();
                $t->unsignedInteger('location_id')->nullable();
                $t->enum('status', ['inquiry', 'hold', 'tentative', 'confirmed', 'contracted', 'completed', 'cancelled'])->default('inquiry');
                $t->string('event_type', 60)->nullable();
                $t->date('event_date')->nullable();
                $t->time('start_time')->nullable();
                $t->time('end_time')->nullable();
                $t->unsignedInteger('attendees')->nullable();
                $t->decimal('total_amount', 15, 2)->default(0);
                $t->decimal('discount_amount', 15, 2)->default(0);
                $t->decimal('deposit_amount', 15, 2)->default(0);
                $t->unsignedInteger('erp_invoice_id')->nullable(); // ERP transaction (set in M7)
                $t->text('notes')->nullable();
                $t->unsignedInteger('created_by')->nullable();
                $t->dateTime('confirmed_at')->nullable();
                $t->timestamps();
                $t->index(['business_id', 'status']);
                $t->index(['business_id', 'event_date']);
            });
        }

        if (! Schema::hasTable('bms_booking_halls')) {
            Schema::create('bms_booking_halls', function (Blueprint $t) {
                $t->bigIncrements('id');
                $t->unsignedInteger('business_id');
                $t->unsignedBigInteger('booking_id');
                $t->unsignedBigInteger('hall_id');
                $t->date('event_date');
                $t->enum('slot', ['full_day', 'morning', 'evening'])->default('full_day');
                $t->time('start_time')->nullable();
                $t->time('end_time')->nullable();
                $t->unsignedBigInteger('package_id')->nullable();
                $t->json('addons')->nullable();
                $t->decimal('price', 15, 2)->default(0);
                $t->timestamps();
                $t->index(['business_id', 'booking_id']);
                $t->index(['hall_id', 'event_date']);
            });
        }

        if (! Schema::hasTable('bms_hall_availability')) {
            Schema::create('bms_hall_availability', function (Blueprint $t) {
                $t->bigIncrements('id');
                $t->unsignedInteger('business_id');
                $t->unsignedBigInteger('hall_id');
                $t->date('date');
                $t->enum('slot', ['full_day', 'morning', 'evening'])->default('full_day');
                $t->enum('status', ['hold', 'tentative', 'booked', 'blocked'])->default('hold');
                $t->unsignedBigInteger('booking_id')->nullable();
                $t->string('hold_token', 64)->nullable();
                $t->dateTime('hold_expires_at')->nullable();
                $t->unsignedInteger('created_by')->nullable();
                $t->string('notes', 255)->nullable();
                $t->timestamps();
                // DB-level double-booking prevention: one occupied row per hall/date/slot
                $t->unique(['hall_id', 'date', 'slot']);
                $t->index(['business_id', 'date']);
                $t->index(['hold_expires_at']);
            });
        }
    }

    public function down(): void
    {
        Schema::dropIfExists('bms_hall_availability');
        Schema::dropIfExists('bms_booking_halls');
        Schema::dropIfExists('bms_bookings');
    }
};
