<?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('professionals', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->string('pro_code')->unique();
            $table->unsignedBigInteger('city_id')->nullable()->index();
            $table->unsignedBigInteger('hub_id')->nullable()->index();
            $table->string('onboarding_status', 60)->default('lead')->index();
            $table->string('employment_type', 40)->default('partner');
            $table->decimal('rating_avg', 4, 2)->default(0);
            $table->unsignedInteger('completed_jobs_count')->default(0);
            $table->string('status', 40)->default('lead')->index();
            $table->timestamps();
        });

        Schema::create('professional_applications', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->nullable()->index();
            $table->string('name');
            $table->string('phone', 32)->index();
            $table->string('gender', 32)->nullable();
            $table->unsignedBigInteger('city_id')->nullable()->index();
            $table->string('source', 40)->default('app');
            $table->string('referral_code')->nullable()->index();
            $table->string('status', 60)->default('lead')->index();
            $table->timestamps();
        });

        Schema::create('professional_documents', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->string('document_type', 60);
            $table->text('document_number_encrypted')->nullable();
            $table->string('file_path')->nullable();
            $table->string('verification_status', 40)->default('pending')->index();
            $table->unsignedBigInteger('verified_by')->nullable();
            $table->timestamp('verified_at')->nullable();
            $table->timestamps();
        });

        Schema::create('professional_skills', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->unsignedBigInteger('skill_id')->index();
            $table->string('level', 40)->default('trained');
            $table->timestamp('certified_at')->nullable();
            $table->timestamps();
        });

        Schema::create('professional_availabilities', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->unsignedTinyInteger('day_of_week');
            $table->time('start_time');
            $table->time('end_time');
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('professional_shifts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->unsignedBigInteger('hub_id')->nullable()->index();
            $table->timestamp('starts_at');
            $table->timestamp('ends_at');
            $table->string('status', 40)->default('scheduled')->index();
            $table->decimal('check_in_lat', 10, 7)->nullable();
            $table->decimal('check_in_lng', 10, 7)->nullable();
            $table->decimal('check_out_lat', 10, 7)->nullable();
            $table->decimal('check_out_lng', 10, 7)->nullable();
            $table->timestamps();
        });

        Schema::create('professional_locations', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->decimal('lat', 10, 7);
            $table->decimal('lng', 10, 7);
            $table->decimal('accuracy', 8, 2)->nullable();
            $table->timestamp('captured_at')->index();
            $table->timestamps();
        });

        Schema::create('assignment_offers', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('professional_id')->index();
            $table->decimal('score', 8, 2)->default(0);
            $table->string('status', 40)->default('offered')->index();
            $table->timestamp('offered_at');
            $table->timestamp('expires_at');
            $table->timestamp('responded_at')->nullable();
            $table->timestamps();
        });

        Schema::create('booking_assignments', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('professional_id')->index();
            $table->string('assigned_by_type', 40)->default('system');
            $table->unsignedBigInteger('assigned_by_id')->nullable();
            $table->string('assignment_type', 40)->default('auto');
            $table->string('status', 40)->default('assigned')->index();
            $table->timestamp('assigned_at');
            $table->timestamp('accepted_at')->nullable();
            $table->timestamp('arrived_at')->nullable();
            $table->timestamp('started_at')->nullable();
            $table->timestamp('completed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('payments', function (Blueprint $table) {
            $table->id();
            $table->string('payment_number')->unique();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('booking_id')->nullable()->index();
            $table->unsignedBigInteger('quote_id')->nullable()->index();
            $table->string('gateway', 40)->default('local');
            $table->string('gateway_order_id')->nullable()->index();
            $table->decimal('amount', 10, 2);
            $table->string('currency', 8)->default('INR');
            $table->string('status', 40)->default('created')->index();
            $table->timestamp('paid_at')->nullable();
            $table->timestamps();
        });

        Schema::create('payment_attempts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('payment_id')->index();
            $table->string('gateway_payment_id')->nullable()->index();
            $table->string('method', 40)->default('upi');
            $table->string('status', 40)->default('created')->index();
            $table->json('response_json')->nullable();
            $table->timestamps();
        });

        Schema::create('payment_webhooks', function (Blueprint $table) {
            $table->id();
            $table->string('gateway', 40);
            $table->string('event_type');
            $table->string('gateway_event_id')->nullable()->index();
            $table->json('payload_json');
            $table->boolean('signature_valid')->default(false);
            $table->timestamp('processed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('invoices', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('user_id')->index();
            $table->string('invoice_number')->unique();
            $table->string('gst_number')->nullable();
            $table->decimal('subtotal', 10, 2)->default(0);
            $table->decimal('tax_total', 10, 2)->default(0);
            $table->decimal('total', 10, 2)->default(0);
            $table->string('pdf_path')->nullable();
            $table->timestamp('issued_at');
            $table->timestamps();
        });

        Schema::create('wallet_accounts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->unique();
            $table->decimal('balance', 10, 2)->default(0);
            $table->string('currency', 8)->default('INR');
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('wallet_transactions', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('wallet_account_id')->index();
            $table->string('transaction_type', 40);
            $table->decimal('amount', 10, 2);
            $table->decimal('balance_after', 10, 2);
            $table->string('reference_type')->nullable();
            $table->unsignedBigInteger('reference_id')->nullable();
            $table->timestamp('expires_at')->nullable();
            $table->timestamps();
        });

        Schema::create('refunds', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('payment_id')->nullable()->index();
            $table->string('refund_number')->unique();
            $table->decimal('amount', 10, 2);
            $table->string('reason')->nullable();
            $table->string('status', 40)->default('requested')->index();
            $table->string('gateway_refund_id')->nullable()->index();
            $table->unsignedBigInteger('approved_by')->nullable();
            $table->timestamp('processed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('professional_earnings', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('professional_id')->index();
            $table->unsignedBigInteger('booking_id')->nullable()->index();
            $table->string('earning_type', 40)->default('service_fee');
            $table->decimal('amount', 10, 2);
            $table->string('status', 40)->default('pending')->index();
            $table->timestamps();
        });

        Schema::create('payout_batches', function (Blueprint $table) {
            $table->id();
            $table->string('batch_number')->unique();
            $table->date('period_start');
            $table->date('period_end');
            $table->decimal('total_amount', 12, 2)->default(0);
            $table->string('status', 40)->default('draft')->index();
            $table->timestamps();
        });

        Schema::create('payout_items', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('payout_batch_id')->index();
            $table->unsignedBigInteger('professional_id')->nullable()->index();
            $table->unsignedBigInteger('buddy_id')->nullable()->index();
            $table->decimal('amount', 10, 2);
            $table->string('status', 40)->default('pending')->index();
            $table->string('bank_reference')->nullable();
            $table->timestamps();
        });

        Schema::create('buddies', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->string('buddy_code')->unique();
            $table->text('pan_encrypted')->nullable();
            $table->text('bank_account_encrypted')->nullable();
            $table->string('bank_ifsc')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('referral_codes', function (Blueprint $table) {
            $table->id();
            $table->string('owner_type', 40);
            $table->unsignedBigInteger('owner_id')->nullable();
            $table->string('code')->unique();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('referral_leads', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('referral_code_id')->index();
            $table->string('referred_phone', 32)->index();
            $table->unsignedBigInteger('professional_application_id')->nullable()->index();
            $table->string('status', 60)->default('lead_created')->index();
            $table->timestamp('expires_at')->nullable();
            $table->timestamps();
        });

        Schema::create('referral_rewards', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('referral_lead_id')->index();
            $table->unsignedBigInteger('buddy_id')->index();
            $table->decimal('amount', 10, 2)->default(3000);
            $table->string('status', 40)->default('pending')->index();
            $table->timestamp('eligible_at')->nullable();
            $table->timestamp('paid_at')->nullable();
            $table->timestamps();
        });

        Schema::create('reviews', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('booking_id')->index();
            $table->unsignedBigInteger('user_id')->index();
            $table->unsignedBigInteger('professional_id')->nullable()->index();
            $table->unsignedTinyInteger('rating');
            $table->text('review_text')->nullable();
            $table->string('status', 40)->default('visible')->index();
            $table->timestamps();
        });

        Schema::create('support_tickets', function (Blueprint $table) {
            $table->id();
            $table->string('ticket_number')->unique();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->unsignedBigInteger('booking_id')->nullable()->index();
            $table->string('category', 80)->default('general');
            $table->string('priority', 40)->default('normal')->index();
            $table->string('status', 40)->default('open')->index();
            $table->unsignedBigInteger('assigned_to')->nullable()->index();
            $table->timestamp('first_response_due_at')->nullable();
            $table->timestamp('resolution_due_at')->nullable();
            $table->timestamps();
        });

        Schema::create('support_messages', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('support_ticket_id')->index();
            $table->string('sender_type', 40);
            $table->unsignedBigInteger('sender_id')->nullable();
            $table->text('message');
            $table->string('attachment_path')->nullable();
            $table->timestamps();
        });

        Schema::create('cms_pages', function (Blueprint $table) {
            $table->id();
            $table->string('slug')->unique();
            $table->string('title');
            $table->longText('body_html');
            $table->string('version', 40)->default('1.0');
            $table->string('status', 40)->default('published')->index();
            $table->timestamp('published_at')->nullable();
            $table->timestamps();
        });

        Schema::create('faqs', function (Blueprint $table) {
            $table->id();
            $table->string('question');
            $table->text('answer');
            $table->string('category')->nullable();
            $table->unsignedInteger('sort_order')->default(0);
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
        });

        Schema::create('app_configs', function (Blueprint $table) {
            $table->id();
            $table->string('key')->unique();
            $table->json('value_json');
            $table->string('description')->nullable();
            $table->timestamps();
        });

        Schema::create('notification_templates', function (Blueprint $table) {
            $table->id();
            $table->string('channel', 40);
            $table->string('template_key');
            $table->string('subject')->nullable();
            $table->text('body');
            $table->json('variables_json')->nullable();
            $table->string('status', 40)->default('active')->index();
            $table->timestamps();
            $table->unique(['channel', 'template_key']);
        });

        Schema::create('communication_logs', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->string('channel', 40);
            $table->string('template_key')->nullable();
            $table->string('recipient');
            $table->json('payload_json')->nullable();
            $table->string('provider')->default('local');
            $table->string('provider_reference')->nullable();
            $table->string('status', 40)->default('queued')->index();
            $table->timestamp('sent_at')->nullable();
            $table->timestamps();
        });

        Schema::create('analytics_events', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id')->nullable()->index();
            $table->string('event_name')->index();
            $table->json('event_properties_json')->nullable();
            $table->string('device_id')->nullable();
            $table->timestamp('occurred_at')->index();
            $table->timestamps();
        });

        Schema::create('audit_logs', function (Blueprint $table) {
            $table->id();
            $table->string('actor_type')->nullable();
            $table->unsignedBigInteger('actor_id')->nullable();
            $table->string('action')->index();
            $table->string('auditable_type')->nullable();
            $table->unsignedBigInteger('auditable_id')->nullable();
            $table->json('old_values_json')->nullable();
            $table->json('new_values_json')->nullable();
            $table->string('ip_address', 64)->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        foreach (array_reverse([
            'audit_logs',
            'analytics_events',
            'communication_logs',
            'notification_templates',
            'app_configs',
            'faqs',
            'cms_pages',
            'support_messages',
            'support_tickets',
            'reviews',
            'referral_rewards',
            'referral_leads',
            'referral_codes',
            'buddies',
            'payout_items',
            'payout_batches',
            'professional_earnings',
            'refunds',
            'wallet_transactions',
            'wallet_accounts',
            'invoices',
            'payment_webhooks',
            'payment_attempts',
            'payments',
            'booking_assignments',
            'assignment_offers',
            'professional_locations',
            'professional_shifts',
            'professional_availabilities',
            'professional_skills',
            'professional_documents',
            'professional_applications',
            'professionals',
        ]) as $table) {
            Schema::dropIfExists($table);
        }
    }
};
