<?php

declare(strict_types=1);

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('signature_requests', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('business_document_id')->constrained('business_documents')->cascadeOnDelete();
            $table->foreignUuid('deal_id')->nullable()->constrained('sales_deals')->nullOnDelete();
            $table->foreignUuid('client_portal_id')->nullable();
            $table->string('provider', 40)->default('native');
            $table->string('mode', 20)->default('parallel');
            $table->string('status', 40)->default('draft');
            $table->string('title');
            $table->text('message')->nullable();
            $table->timestamp('expires_at')->nullable();
            $table->timestamp('sent_at')->nullable();
            $table->timestamp('completed_at')->nullable();
            $table->timestamp('cancelled_at')->nullable();
            $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignId('responsible_user_id')->nullable()->constrained('users')->nullOnDelete();
            $table->string('provider_external_id')->nullable();
            $table->json('meta')->nullable();
            $table->timestamps();

            $table->index(['tenant_id', 'status']);
            $table->index(['tenant_id', 'business_document_id']);
            $table->index(['tenant_id', 'deal_id']);
        });

        if (Schema::hasTable('client_portals')) {
            Schema::table('signature_requests', function (Blueprint $table): void {
                $table->foreign('client_portal_id')->references('id')->on('client_portals')->nullOnDelete();
            });
        }

        Schema::table('business_documents', function (Blueprint $table): void {
            $table->string('signature_status', 40)->nullable()->after('status');
            $table->uuid('signature_request_id')->nullable()->after('signature_status');
        });

        Schema::table('business_documents', function (Blueprint $table): void {
            $table->foreign('signature_request_id')->references('id')->on('signature_requests')->nullOnDelete();
        });

        Schema::create('signature_signers', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('signature_request_id')->constrained('signature_requests')->cascadeOnDelete();
            $table->foreignUuid('contact_id')->nullable()->constrained('contacts')->nullOnDelete();
            $table->string('name');
            $table->string('email')->nullable();
            $table->string('phone', 30)->nullable();
            $table->string('role', 20)->default('buyer');
            $table->unsignedSmallInteger('order')->default(1);
            $table->string('status', 20)->default('pending');
            $table->string('access_token_hash', 64)->unique();
            $table->string('access_token_prefix', 12)->index();
            $table->timestamp('signed_at')->nullable();
            $table->timestamp('rejected_at')->nullable();
            $table->timestamp('viewed_at')->nullable();
            $table->string('otp_hash', 64)->nullable();
            $table->timestamp('otp_expires_at')->nullable();
            $table->unsignedTinyInteger('otp_attempts')->default(0);
            $table->string('typed_name')->nullable();
            $table->timestamps();

            $table->index(['signature_request_id', 'order']);
            $table->index(['tenant_id', 'status']);
        });

        Schema::create('signature_steps', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('signature_request_id')->constrained('signature_requests')->cascadeOnDelete();
            $table->unsignedSmallInteger('order_index');
            $table->string('label');
            $table->string('status', 20)->default('pending');
            $table->timestamp('opened_at')->nullable();
            $table->timestamp('completed_at')->nullable();
            $table->timestamps();

            $table->unique(['signature_request_id', 'order_index']);
        });

        Schema::create('signature_evidences', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('signature_request_id')->constrained('signature_requests')->cascadeOnDelete();
            $table->foreignUuid('signer_id')->constrained('signature_signers')->cascadeOnDelete();
            $table->string('kind', 20);
            $table->json('payload')->nullable();
            $table->string('ip', 45)->nullable();
            $table->string('user_agent', 512)->nullable();
            $table->string('device', 40)->nullable();
            $table->timestamp('created_at')->useCurrent();

            $table->index(['signer_id', 'created_at']);
        });

        Schema::create('signature_audits', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('signature_request_id')->constrained('signature_requests')->cascadeOnDelete();
            $table->string('event', 40);
            $table->string('actor_type', 20)->default('system');
            $table->foreignId('actor_user_id')->nullable()->constrained('users')->nullOnDelete();
            $table->foreignUuid('signer_id')->nullable()->constrained('signature_signers')->nullOnDelete();
            $table->json('payload')->nullable();
            $table->string('message')->nullable();
            $table->timestamp('created_at')->useCurrent();

            $table->index(['signature_request_id', 'created_at']);
        });

        Schema::create('signature_reminders', function (Blueprint $table): void {
            $table->uuid('id')->primary();
            $table->foreignUuid('tenant_id')->constrained('tenants')->cascadeOnDelete();
            $table->foreignUuid('signature_request_id')->constrained('signature_requests')->cascadeOnDelete();
            $table->foreignUuid('signer_id')->constrained('signature_signers')->cascadeOnDelete();
            $table->string('channel', 20);
            $table->timestamp('scheduled_at');
            $table->timestamp('sent_at')->nullable();
            $table->string('status', 20)->default('pending');
            $table->timestamps();

            $table->index(['signer_id', 'scheduled_at']);
            $table->index(['status', 'scheduled_at']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('signature_reminders');
        Schema::dropIfExists('signature_audits');
        Schema::dropIfExists('signature_evidences');
        Schema::dropIfExists('signature_steps');
        Schema::dropIfExists('signature_signers');

        Schema::table('business_documents', function (Blueprint $table): void {
            $table->dropForeign(['signature_request_id']);
            $table->dropColumn(['signature_status', 'signature_request_id']);
        });

        Schema::dropIfExists('signature_requests');
    }
};
