<?php

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

return new class extends Migration
{
    public function up()
    {
        Schema::create('auth_otps', function (Blueprint $table) {
            $table->id();
            $table->string('phone', 32)->index();
            $table->string('purpose', 40)->default('login');
            $table->string('otp_hash');
            $table->timestamp('expires_at');
            $table->timestamp('verified_at')->nullable();
            $table->unsignedTinyInteger('attempts')->default(0);
            $table->string('ip_address', 64)->nullable();
            $table->timestamps();
        });

        Schema::create('user_devices', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->index();
            $table->string('device_type', 20)->default('android');
            $table->string('device_token')->nullable();
            $table->string('app_version', 40)->nullable();
            $table->string('os_version', 80)->nullable();
            $table->timestamp('last_seen_at')->nullable();
            $table->timestamps();
        });

        Schema::create('user_consents', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->index();
            $table->string('consent_type', 40);
            $table->string('version', 40);
            $table->timestamp('accepted_at');
            $table->string('ip_address', 64)->nullable();
            $table->timestamps();
        });

        Schema::create('account_deletion_requests', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->string('phone', 32)->index();
            $table->string('status', 40)->default('requested')->index();
            $table->text('reason')->nullable();
            $table->timestamp('requested_at');
            $table->timestamp('completed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('cities', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('state')->nullable();
            $table->string('country')->default('India');
            $table->string('timezone')->default('Asia/Kolkata');
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('localities', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('city_id')->index();
            $table->string('name');
            $table->string('slug');
            $table->string('pincode', 12)->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
            $table->unique(['city_id', 'slug']);
        });

        Schema::create('hubs', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('city_id')->index();
            $table->unsignedBigInteger('locality_id')->nullable()->index();
            $table->string('name');
            $table->text('address')->nullable();
            $table->decimal('lat', 10, 7)->nullable();
            $table->decimal('lng', 10, 7)->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_areas', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('city_id')->index();
            $table->unsignedBigInteger('locality_id')->nullable()->index();
            $table->unsignedBigInteger('hub_id')->nullable()->index();
            $table->string('name');
            $table->json('polygon_json')->nullable();
            $table->boolean('is_instant_enabled')->default(true);
            $table->boolean('is_scheduled_enabled')->default(true);
            $table->boolean('is_recurring_enabled')->default(true);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('customer_addresses', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('city_id')->nullable()->index();
            $table->unsignedBigInteger('locality_id')->nullable()->index();
            $table->string('label')->default('Home');
            $table->string('address_line_1');
            $table->string('address_line_2')->nullable();
            $table->string('landmark')->nullable();
            $table->string('pincode', 12)->nullable();
            $table->decimal('lat', 10, 7)->nullable();
            $table->decimal('lng', 10, 7)->nullable();
            $table->string('society_name')->nullable();
            $table->string('floor')->nullable();
            $table->text('gate_instructions')->nullable();
            $table->boolean('has_pets')->default(false);
            $table->boolean('is_default')->default(false);
            $table->timestamps();
        });

        Schema::create('service_categories', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->text('description')->nullable();
            $table->string('icon_path')->nullable();
            $table->unsignedInteger('sort_order')->default(0);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('services', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('category_id')->index();
            $table->string('name');
            $table->string('slug')->unique();
            $table->text('description')->nullable();
            $table->string('service_type', 40)->default('task')->index();
            $table->unsignedInteger('default_duration_minutes')->default(60);
            $table->unsignedInteger('min_duration_minutes')->nullable();
            $table->unsignedInteger('max_duration_minutes')->nullable();
            $table->boolean('is_stackable')->default(true);
            $table->boolean('requires_photos')->default(false);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_variants', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('service_id')->index();
            $table->string('name');
            $table->text('description')->nullable();
            $table->unsignedInteger('duration_minutes')->default(60);
            $table->string('base_unit', 30)->default('visit');
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_addons', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('service_id')->index();
            $table->string('name');
            $table->unsignedInteger('duration_minutes')->default(15);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_checklist_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('service_id')->index();
            $table->string('title');
            $table->string('type', 40)->default('completion_required');
            $table->boolean('is_required')->default(true);
            $table->unsignedInteger('sort_order')->default(0);
            $table->timestamps();
        });

        Schema::create('skills', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_skill_requirements', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('service_id')->index();
            $table->unsignedBigInteger('skill_id')->index();
            $table->string('required_level', 40)->default('trained');
            $table->timestamps();
        });

        Schema::create('service_availability', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('service_id')->index();
            $table->unsignedBigInteger('city_id')->index();
            $table->unsignedBigInteger('locality_id')->nullable()->index();
            $table->boolean('is_instant_enabled')->default(true);
            $table->boolean('is_scheduled_enabled')->default(true);
            $table->boolean('is_recurring_enabled')->default(true);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('price_books', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->unsignedBigInteger('city_id')->nullable()->index();
            $table->timestamp('starts_at')->nullable();
            $table->timestamp('ends_at')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('service_prices', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('price_book_id')->index();
            $table->unsignedBigInteger('service_id')->index();
            $table->unsignedBigInteger('variant_id')->nullable()->index();
            $table->decimal('base_price', 10, 2);
            $table->string('currency', 8)->default('INR');
            $table->unsignedInteger('duration_minutes')->default(60);
            $table->timestamps();
        });

        Schema::create('fee_rules', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('fee_type', 40);
            $table->string('calculation_type', 20)->default('fixed');
            $table->decimal('value', 10, 2)->default(0);
            $table->json('conditions_json')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('tax_rules', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('tax_type', 40)->default('gst');
            $table->decimal('percent', 6, 2)->default(0);
            $table->string('hsn_sac')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('coupons', function (Blueprint $table) {
            $table->id();
            $table->string('code')->unique();
            $table->string('description')->nullable();
            $table->string('discount_type', 20)->default('fixed');
            $table->decimal('discount_value', 10, 2)->default(0);
            $table->decimal('max_discount', 10, 2)->nullable();
            $table->decimal('min_order_amount', 10, 2)->nullable();
            $table->timestamp('starts_at')->nullable();
            $table->timestamp('ends_at')->nullable();
            $table->unsignedInteger('usage_limit')->nullable();
            $table->unsignedInteger('per_user_limit')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('carts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('address_id')->nullable()->index();
            $table->string('booking_type', 40)->default('instant')->index();
            $table->timestamp('scheduled_start_at')->nullable();
            $table->json('recurring_json')->nullable();
            $table->string('coupon_code')->nullable();
            $table->boolean('use_wallet')->default(false);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('cart_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('cart_id')->index();
            $table->unsignedBigInteger('service_id')->index();
            $table->unsignedBigInteger('variant_id')->nullable()->index();
            $table->unsignedInteger('quantity')->default(1);
            $table->unsignedInteger('duration_minutes')->nullable();
            $table->text('notes')->nullable();
            $table->timestamps();
        });

        Schema::create('cart_item_addons', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('cart_item_id')->index();
            $table->unsignedBigInteger('addon_id')->index();
            $table->unsignedInteger('quantity')->default(1);
            $table->timestamps();
        });

        Schema::create('quotes', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('cart_id')->index();
            $table->unsignedBigInteger('user_id')->index();
            $table->string('quote_number')->unique();
            $table->unsignedBigInteger('price_book_id')->nullable()->index();
            $table->json('pricing_snapshot_json');
            $table->decimal('subtotal', 10, 2)->default(0);
            $table->decimal('fees_total', 10, 2)->default(0);
            $table->decimal('discount_total', 10, 2)->default(0);
            $table->decimal('wallet_applied', 10, 2)->default(0);
            $table->decimal('tax_total', 10, 2)->default(0);
            $table->decimal('payable_total', 10, 2)->default(0);
            $table->timestamp('expires_at');
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('recurring_plans', function (Blueprint $table) {
            $table->id();
            $table->string('plan_number')->unique();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('address_id')->index();
            $table->unsignedBigInteger('quote_id')->nullable()->index();
            $table->string('cadence', 40)->default('weekly');
            $table->json('days_of_week_json')->nullable();
            $table->date('start_date');
            $table->date('end_date')->nullable();
            $table->time('preferred_start_time')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamp('paused_at')->nullable();
            $table->timestamp('cancelled_at')->nullable();
            $table->timestamps();
        });

        Schema::create('bookings', function (Blueprint $table) {
            $table->id();
            $table->string('booking_number')->unique();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('address_id')->index();
            $table->unsignedBigInteger('quote_id')->nullable()->index();
            $table->unsignedBigInteger('recurring_plan_id')->nullable()->index();
            $table->string('booking_type', 40)->default('instant')->index();
            $table->timestamp('scheduled_start_at')->nullable()->index();
            $table->timestamp('scheduled_end_at')->nullable();
            $table->string('status', 40)->default('confirmed')->index();
            $table->string('payment_status', 40)->default('unpaid')->index();
            $table->string('assignment_status', 40)->default('unassigned')->index();
            $table->decimal('subtotal', 10, 2)->default(0);
            $table->decimal('fees_total', 10, 2)->default(0);
            $table->decimal('discount_total', 10, 2)->default(0);
            $table->decimal('tax_total', 10, 2)->default(0);
            $table->decimal('payable_total', 10, 2)->default(0);
            $table->text('customer_notes')->nullable();
            $table->string('cancellation_reason')->nullable();
            $table->string('cancelled_by_type')->nullable();
            $table->unsignedBigInteger('cancelled_by_id')->nullable();
            $table->timestamp('cancelled_at')->nullable();
            $table->timestamp('completed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('booking_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('service_id')->index();
            $table->unsignedBigInteger('variant_id')->nullable()->index();
            $table->string('service_name_snapshot');
            $table->unsignedInteger('quantity')->default(1);
            $table->unsignedInteger('duration_minutes')->default(60);
            $table->json('price_snapshot_json')->nullable();
            $table->string('status', 40)->default('pending')->index();
            $table->timestamps();
        });

        Schema::create('booking_status_histories', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->string('from_status')->nullable();
            $table->string('to_status');
            $table->string('actor_type')->nullable();
            $table->unsignedBigInteger('actor_id')->nullable();
            $table->string('reason')->nullable();
            $table->json('metadata_json')->nullable();
            $table->timestamps();
        });

        Schema::create('recurring_sessions', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('recurring_plan_id')->index();
            $table->unsignedBigInteger('booking_id')->nullable()->index();
            $table->date('session_date')->index();
            $table->timestamp('scheduled_start_at')->nullable();
            $table->timestamp('scheduled_end_at')->nullable();
            $table->string('status', 40)->default('planned')->index();
            $table->timestamps();
        });
    }

    public function down()
    {
        foreach (array_reverse([
            'recurring_sessions',
            'booking_status_histories',
            'booking_items',
            'bookings',
            'recurring_plans',
            'quotes',
            'cart_item_addons',
            'cart_items',
            'carts',
            'coupons',
            'tax_rules',
            'fee_rules',
            'service_prices',
            'price_books',
            'service_availability',
            'service_skill_requirements',
            'skills',
            'service_checklist_items',
            'service_addons',
            'service_variants',
            'services',
            'service_categories',
            'customer_addresses',
            'service_areas',
            'hubs',
            'localities',
            'cities',
            'account_deletion_requests',
            'user_consents',
            'user_devices',
            'auth_otps',
        ]) as $table) {
            Schema::dropIfExists($table);
        }
    }
};
