<?php

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

/**
 * Contract-grade booking layer:
 *  - bms_payment_schedules : structured deposit/installment/balance plan per booking
 *  - bms_booking_events    : append-only audit trail (confirmed/contracted/cancelled/
 *                            rescheduled/payment/refund) for the money + lifecycle path
 *  - bms_bookings (ALTER)  : cancellation + reschedule bookkeeping columns
 */
return new class extends Migration {
    public function up(): void
    {
        if (! Schema::hasTable('bms_payment_schedules')) {
            Schema::create('bms_payment_schedules', function (Blueprint $t) {
                $t->bigIncrements('id');
                $t->unsignedInteger('business_id');
                $t->unsignedBigInteger('booking_id');
                $t->string('label', 60);
                $t->enum('kind', ['deposit', 'installment', 'balance'])->default('installment');
                $t->date('due_date')->nullable();
                $t->decimal('percent', 6, 3)->default(0);
                $t->decimal('amount', 15, 2)->default(0);
                $t->decimal('paid_amount', 15, 2)->default(0);
                $t->enum('status', ['pending', 'partial', 'paid', 'overdue', 'cancelled'])->default('pending');
                $t->unsignedInteger('sort_order')->default(0);
                $t->timestamps();
                $t->index(['business_id', 'booking_id']);
                $t->index(['business_id', 'status']);
            });
        }

        if (! Schema::hasTable('bms_booking_events')) {
            Schema::create('bms_booking_events', function (Blueprint $t) {
                $t->bigIncrements('id');
                $t->unsignedInteger('business_id');
                $t->unsignedBigInteger('booking_id');
                $t->string('type', 40); // confirmed|contracted|completed|cancelled|rescheduled|payment|refund|note
                $t->json('payload')->nullable();
                $t->unsignedInteger('user_id')->nullable();
                $t->timestamps();
                $t->index(['business_id', 'booking_id']);
                $t->index(['business_id', 'type']);
            });
        }

        Schema::table('bms_bookings', function (Blueprint $t) {
            if (! Schema::hasColumn('bms_bookings', 'cancelled_at')) {
                $t->dateTime('cancelled_at')->nullable()->after('confirmed_at');
            }
            if (! Schema::hasColumn('bms_bookings', 'cancelled_by')) {
                $t->unsignedInteger('cancelled_by')->nullable()->after('cancelled_at');
            }
            if (! Schema::hasColumn('bms_bookings', 'cancellation_reason')) {
                $t->string('cancellation_reason', 255)->nullable()->after('cancelled_by');
            }
            if (! Schema::hasColumn('bms_bookings', 'penalty_percent')) {
                $t->decimal('penalty_percent', 6, 3)->nullable()->after('cancellation_reason');
            }
            if (! Schema::hasColumn('bms_bookings', 'penalty_amount')) {
                $t->decimal('penalty_amount', 15, 2)->nullable()->after('penalty_percent');
            }
            if (! Schema::hasColumn('bms_bookings', 'refund_amount')) {
                $t->decimal('refund_amount', 15, 2)->nullable()->after('penalty_amount');
            }
            if (! Schema::hasColumn('bms_bookings', 'rescheduled_from')) {
                $t->date('rescheduled_from')->nullable()->after('refund_amount');
            }
            if (! Schema::hasColumn('bms_bookings', 'reschedule_count')) {
                $t->unsignedInteger('reschedule_count')->default(0)->after('rescheduled_from');
            }
            if (! Schema::hasColumn('bms_bookings', 'contracted_at')) {
                $t->dateTime('contracted_at')->nullable()->after('reschedule_count');
            }
            if (! Schema::hasColumn('bms_bookings', 'completed_at')) {
                $t->dateTime('completed_at')->nullable()->after('contracted_at');
            }
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('bms_payment_schedules');
        Schema::dropIfExists('bms_booking_events');
        Schema::table('bms_bookings', function (Blueprint $t) {
            foreach ([
                'cancelled_at', 'cancelled_by', 'cancellation_reason', 'penalty_percent',
                'penalty_amount', 'refund_amount', 'rescheduled_from', 'reschedule_count',
                'contracted_at', 'completed_at',
            ] as $col) {
                if (Schema::hasColumn('bms_bookings', $col)) {
                    $t->dropColumn($col);
                }
            }
        });
    }
};
