<?php

namespace App\Console\Commands;

use App\Models\Organization;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Migrate User to Organization Command
 *
 * This command safely migrates a User model to an Organization model while preserving
 * all associated relationships, accounts, and data.
 *
 * IMPORTANT: This is a one-way migration that cannot be easily reversed.
 * Always run with --dry-run first to preview changes.
 *
 * The migration process:
 * 1. Creates a new Organization with all User data
 * 2. Updates all polymorphic relationships to point to the new Organization
 * 3. Migrates pivot table relationships (bank management, etc.)
 * 4. Updates permission system references
 * 5. Re-indexes Elasticsearch and clears caches
 *
 * Safety validations prevent migration of:
 * - Super Admin users
 * - Users with critical system permissions
 * - Users with conflicting names/emails
 * - Users currently online
 *
 * @author Claude Code
 * @version 1.0
 */
class MigrateUserToOrganizationCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'migrate:user-to-organization {user_id} {--dry-run : Preview changes without executing them}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Migrate a User model to an Organization model while preserving all relationships and data';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $userId = $this->argument('user_id');
        $dryRun = $this->option('dry-run');

        if ($dryRun) {
            $this->info('DRY RUN MODE - No changes will be made');
            $this->newLine();
        }

        // Validate user exists
        $user = User::find($userId);
        if (!$user) {
            $this->error("User with ID {$userId} not found");
            return 1;
        }

        // Safety validations
        $validationResult = $this->validateUserForMigration($user);

        // Handle blocking errors (cannot proceed)
        if (!empty($validationResult['blocking_errors'])) {
            $this->error("Migration validation failed:");
            foreach ($validationResult['blocking_errors'] as $error) {
                $this->line("   • {$error}");
            }
            return 1;
        }

        // Handle warnings that require confirmation
        if (!empty($validationResult['warnings'])) {
            $this->warn("Migration warnings:");
            foreach ($validationResult['warnings'] as $warning) {
                $this->line("   • {$warning}");
            }

            if (!$dryRun && !$this->confirm('Do you want to continue with the migration despite these warnings?', false)) {
                $this->info('Migration cancelled by user.');
                return 0;
            }
        }

        // Handle specific organization management conflicts
        if (!empty($validationResult['organization_conflicts'])) {
            $this->warn("Organization Management Conflicts:");
            foreach ($validationResult['organization_conflicts'] as $conflict) {
                $this->line("   • {$conflict}");
            }

            if (!$dryRun && !$this->confirm('Do you still want to migrate? All organization management relationships will be removed.', false)) {
                $this->info('Migration cancelled by user.');
                return 0;
            }
        }

        $this->info("Migrating User '{$user->name}' (ID: {$userId}) to Organization");
        $this->newLine();

        if ($dryRun) {
            return $this->previewMigration($user);
        }

        return $this->executeMigration($user);
    }

    /**
     * Preview what the migration would do
     */
    private function previewMigration(User $user): int
    {
        $this->info('MIGRATION PREVIEW:');
        $this->line('─────────────────────');

        // Check what would be created
        $this->info("Would create Organization:");
        $this->line("   Name: {$user->name}");
        $this->line("   Email: {$user->email}");
        $this->line("   Limits: min=" . timebank_config('accounts.organization.limit_min', 0) .
                   ", max=" . timebank_config('accounts.organization.limit_max', 12000));

        // Show admin cleanup that would happen
        $adminRoles = ['admin', 'super-admin', 'Admin', 'Super Admin'];
        $hasAdminRoles = false;
        foreach ($adminRoles as $roleName) {
            if ($user->hasRole($roleName)) {
                if (!$hasAdminRoles) {
                    $this->line("Would remove admin roles:");
                    $hasAdminRoles = true;
                }
                $this->line("   - {$roleName}");
            }
        }

        $adminCount = $user->admins()->count();
        if ($adminCount > 0) {
            $this->line("Would remove {$adminCount} admin relationships");
        }

        // Show bank management cleanup that would happen
        $bankCount = $user->banksManaged()->count();
        if ($bankCount > 0) {
            $bankNames = $user->banksManaged()->pluck('name')->toArray();
            $this->line("Would remove management of {$bankCount} bank(s):");
            foreach ($bankNames as $bankName) {
                $this->line("   - {$bankName}");
            }
        }

        // Show organization management cleanup that would happen
        $organizationCount = $user->organizations()->count();
        if ($organizationCount > 0) {
            $orgNames = $user->organizations()->pluck('name')->toArray();
            $this->line("Would remove management of {$organizationCount} organization(s):");
            foreach ($orgNames as $orgName) {
                $this->line("   - {$orgName}");
            }
        }

        // Check polymorphic relationships
        $polymorphicTables = $this->getPolymorphicTables();
        foreach ($polymorphicTables as $table => $columns) {
            $count = DB::table($table)
                ->where($columns['type'], 'App\Models\User')
                ->where($columns['id'], $user->id)
                ->count();

            if ($count > 0) {
                $this->line("{$table}: {$count} records to update");
            }
        }

        // Check pivot tables
        $pivotTables = $this->getPivotTables();
        foreach ($pivotTables as $table => $column) {
            $count = DB::table($table)->where($column, $user->id)->count();
            if ($count > 0) {
                $this->line("{$table}: {$count} records to migrate");
            }
        }

        $this->newLine();
        $this->info('Run without --dry-run to execute the migration');

        return 0;
    }

    /**
     * Execute the actual migration
     */
    private function executeMigration(User $user): int
    {
        DB::beginTransaction();

        try {
            $this->info('Starting migration...');

            // Step 1: Remove admin relationships and roles
            $this->removeAdminRelationshipsAndRoles($user);

            // Step 2: Create Organization
            $organization = $this->createOrganizationFromUser($user);
            $this->info("Created Organization with ID: {$organization->id}");

            // Step 3: Update polymorphic relationships
            $this->updatePolymorphicRelationships($user, $organization);

            // Step 4: Update love package relationships
            $this->updateLoveRelationships($user, $organization);

            // Step 5: Handle pivot tables
            $this->updatePivotTables($user, $organization);

            // Step 6: Update direct references
            $this->updateDirectReferences($user, $organization);

            // Step 7: Handle special cases
            $this->handleSpecialCases($user, $organization);

            // Step 8: Delete the original User and cleanup relationships
            $this->deleteUserAndRelationships($user, $organization);

            DB::commit();

            $this->newLine();
            $this->info('Migration completed successfully!');
            $this->info("User ID {$user->id} is now Organization ID {$organization->id}");
            $this->info('Original User record and all relationships deleted');

            return 0;

        } catch (\Exception $e) {
            DB::rollBack();
            $this->error('Migration failed: ' . $e->getMessage());
            Log::error('User to Organization migration failed', [
                'user_id' => $user->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return 1;
        }
    }

    /**
     * Create Organization from User data
     */
    private function createOrganizationFromUser(User $user): Organization
    {
        // Copy all common columns between User and Organization models
        $organizationData = $user->only([
            'name', 'full_name', 'email', 'profile_photo_path',
            'about', 'about_short', 'motivation', 'website',
            'phone', 'phone_public', 'password', 'lang_preference',
            'last_login_at', 'last_login_ip', 'comment', 'cyclos_id',
            'cyclos_salt', 'cyclos_skills', 'email_verified_at',
            'inactive_at', 'deleted_at'
        ]);

        // Set Organization-specific limits from config
        $organizationData['limit_min'] = timebank_config('profiles.organization.limit_min', 0);
        $organizationData['limit_max'] = timebank_config('profiles.organization.limit_max', 6000);

        // Copy timestamps
        $organizationData['created_at'] = $user->created_at;
        $organizationData['updated_at'] = $user->updated_at;

        // Create the organization with fillable fields (don't include love IDs yet)
        $organization = Organization::create($organizationData);

        // Set non-fillable fields directly on the model to bypass mass assignment protection
        $nonFillableFields = [
            'comment', 'cyclos_id', 'cyclos_salt', 'cyclos_skills',
            'email_verified_at', 'inactive_at', 'deleted_at'
        ];

        foreach ($nonFillableFields as $field) {
            if ($user->$field !== null) {
                $organization->$field = $user->$field;
            }
        }

        // Force copy love package IDs from user AFTER organization creation
        // This ensures we preserve the original user's love IDs, not newly generated ones
        if ($user->love_reactant_id) {
            $organization->love_reactant_id = $user->love_reactant_id;
        }
        if ($user->love_reacter_id) {
            $organization->love_reacter_id = $user->love_reacter_id;
        }

        // Save the organization with all additional fields including love IDs
        $organization->save();

        return $organization;
    }

    /**
     * Update all polymorphic relationships
     */
    private function updatePolymorphicRelationships(User $user, Organization $organization): void
    {
        $this->info('Updating polymorphic relationships...');

        $polymorphicTables = $this->getPolymorphicTables();

        foreach ($polymorphicTables as $table => $columns) {
            $count = DB::table($table)
                ->where($columns['type'], 'App\Models\User')
                ->where($columns['id'], $user->id)
                ->update([
                    $columns['type'] => 'App\Models\Organization',
                    $columns['id'] => $organization->id
                ]);

            if ($count > 0) {
                $this->line("   {$table}: Updated {$count} records");
            }
        }

        // Update account limits specifically
        $this->updateAccountLimits($organization);
    }

    /**
     * Update account limits to organization values
     */
    private function updateAccountLimits(Organization $organization): void
    {
        $this->info('Updating account limits and names...');

        $userAccountName = timebank_config('accounts.user.name', 'personal');
        $orgAccountName = timebank_config('accounts.organization.name', 'organization');
        $limitMin = timebank_config('accounts.organization.limit_min', 0);
        $limitMax = timebank_config('accounts.organization.limit_max', 12000);

        // Get all accounts for this organization
        $accounts = DB::table('accounts')
            ->where('accountable_type', 'App\Models\Organization')
            ->where('accountable_id', $organization->id)
            ->get(['id', 'name']);

        $limitsUpdated = 0;
        $namesRenamed = 0;
        $assignedNames = []; // Track names assigned during this migration

        foreach ($accounts as $account) {
            $updateData = [
                'limit_min' => $limitMin,
                'limit_max' => $limitMax
            ];

            // Rename accounts based on their current name
            if ($account->name === $userAccountName) {
                // Rename 'personal' to 'organization' (with numbering if needed)
                $newName = $this->generateUniqueAccountName($organization, $orgAccountName, $assignedNames);
                $updateData['name'] = $newName;
                $assignedNames[] = $newName; // Track this assigned name
                $namesRenamed++;
                $this->line("   Renaming account ID {$account->id}: '{$account->name}' → '{$newName}'");
            } elseif ($account->name === 'gift') {
                // Rename 'gift' to 'donation' (with numbering if needed)
                $newName = $this->generateUniqueAccountName($organization, 'donation', $assignedNames);
                $updateData['name'] = $newName;
                $assignedNames[] = $newName; // Track this assigned name
                $namesRenamed++;
                $this->line("   Renaming account ID {$account->id}: '{$account->name}' → '{$newName}'");
            }

            // Update the account
            DB::table('accounts')
                ->where('id', $account->id)
                ->update($updateData);

            $limitsUpdated++;
        }

        if ($limitsUpdated > 0) {
            $this->line("   Updated limits for {$limitsUpdated} account(s): min={$limitMin}, max={$limitMax}");
        }

        if ($namesRenamed > 0) {
            $this->line("   Renamed {$namesRenamed} account(s) (personal→organization, gift→donation)");
        }

        if ($limitsUpdated === 0) {
            $this->line("   No accounts found to update");
        }
    }

    /**
     * Generate a unique account name for the organization
     */
    private function generateUniqueAccountName(Organization $organization, string $baseName, array $accountsBeingRenamed = []): string
    {
        // Get all existing account names for this organization
        $existingNames = DB::table('accounts')
            ->where('accountable_type', 'App\Models\Organization')
            ->where('accountable_id', $organization->id)
            ->pluck('name')
            ->toArray();

        // Also consider names that are being assigned in this migration batch
        $existingNames = array_merge($existingNames, $accountsBeingRenamed);

        // If base name doesn't exist, use it
        if (!in_array($baseName, $existingNames)) {
            return $baseName;
        }

        // Try numbered versions until we find one that doesn't exist
        $counter = 2;
        while (true) {
            $candidateName = $baseName . ' ' . $counter;
            if (!in_array($candidateName, $existingNames)) {
                return $candidateName;
            }
            $counter++;
        }
    }

    /**
     * Update love package relationships
     */
    private function updateLoveRelationships(User $user, Organization $organization): void
    {
        $this->info('Updating love package relationships...');

        // Update love_reactants type from User to Organization
        if ($user->loveReactant) {
            $updated = DB::table('love_reactants')
                ->where('id', $user->loveReactant->id)
                ->update(['type' => 'App\Models\Organization']);

            if ($updated > 0) {
                $this->line("   love_reactants: Updated type for reactant ID {$user->loveReactant->id}");
            }
        }

        // Update love_reacters type from User to Organization
        if ($user->loveReacter) {
            $updated = DB::table('love_reacters')
                ->where('id', $user->loveReacter->id)
                ->update(['type' => 'App\Models\Organization']);

            if ($updated > 0) {
                $this->line("   love_reacters: Updated type for reacter ID {$user->loveReacter->id}");
            }
        }

        if (!$user->loveReactant && !$user->loveReacter) {
            $this->line("   No love relationships to update");
        }
    }

    /**
     * Handle pivot table migrations
     */
    private function updatePivotTables(User $user, Organization $organization): void
    {
        $this->info('Updating pivot tables...');

        // Handle bank_user -> bank_organization migration
        $bankRelationships = DB::table('bank_user')->where('user_id', $user->id)->get();
        foreach ($bankRelationships as $relationship) {
            // Create new bank_organization relationship
            DB::table('bank_organization')->insertOrIgnore([
                'bank_id' => $relationship->bank_id,
                'organization_id' => $organization->id,
                'created_at' => $relationship->created_at ?? now(),
                'updated_at' => $relationship->updated_at ?? now()
            ]);
        }

        if ($bankRelationships->count() > 0) {
            $this->line("   bank_organization: Migrated {$bankRelationships->count()} relationships");
            // Delete old bank_user relationships
            DB::table('bank_user')->where('user_id', $user->id)->delete();
        }

        // Make the User a manager of the new Organization
        DB::table('organization_user')->insertOrIgnore([
            'organization_id' => $organization->id,
            'user_id' => $user->id,
            'created_at' => now(),
            'updated_at' => now()
        ]);
        $this->line("   organization_user: Added User as manager");

        // Handle other pivot tables
        $pivotTables = $this->getPivotTables();
        foreach ($pivotTables as $table => $column) {
            if ($table === 'bank_user') {
                continue;
            } // Already handled above

            $count = DB::table($table)->where($column, $user->id)->count();
            if ($count > 0) {
                $this->line("   {$table}: {$count} records need manual review");
            }
        }
    }

    /**
     * Update direct references
     */
    private function updateDirectReferences(User $user, Organization $organization): void
    {
        $this->info('Updating direct references...');

        // Handle Spatie Permission tables
        DB::table('model_has_roles')
            ->where('model_type', 'App\Models\User')
            ->where('model_id', $user->id)
            ->update([
                'model_type' => 'App\Models\Organization',
                'model_id' => $organization->id
            ]);

        DB::table('model_has_permissions')
            ->where('model_type', 'App\Models\User')
            ->where('model_id', $user->id)
            ->update([
                'model_type' => 'App\Models\Organization',
                'model_id' => $organization->id
            ]);

        $this->line("   Updated permission system references");
    }

    /**
     * Handle special cases like Elasticsearch, caches, etc.
     */
    private function handleSpecialCases(User $user, Organization $organization): void
    {
        $this->info('Handling special cases...');

        // Re-index in Elasticsearch
        try {
            $organization->searchable();
            $this->line("   Updated Elasticsearch index");
        } catch (\Exception $e) {
            $this->line("   Elasticsearch update failed: " . $e->getMessage());
        }

        // Clear caches
        if (function_exists('cache')) {
            cache()->forget("user.{$user->id}");
            $this->line("   Cleared user cache");
        }
    }

    /**
     * Get polymorphic table mappings
     */
    private function getPolymorphicTables(): array
    {
        $tables = [
            'accounts' => ['type' => 'accountable_type', 'id' => 'accountable_id'],
            'locations' => ['type' => 'locatable_type', 'id' => 'locatable_id'],
            'posts' => ['type' => 'postable_type', 'id' => 'postable_id'],
            'categories' => ['type' => 'categoryable_type', 'id' => 'categoryable_id'],
            'activity_log' => ['type' => 'subject_type', 'id' => 'subject_id'],
        ];

        // Check for optional tables that might exist
        if ($this->tableExists('languagables')) {
            $tables['languagables'] = ['type' => 'languagable_type', 'id' => 'languagable_id'];
        }

        if ($this->tableExists('sociables')) {
            $tables['sociables'] = ['type' => 'sociable_type', 'id' => 'sociable_id'];
        }

        if ($this->tableExists('bank_clients')) {
            $tables['bank_clients'] = ['type' => 'client_type', 'id' => 'client_id'];
        }

        // Love package tables are handled separately in updateLoveRelationships()
        // as they use a different pattern (type column instead of polymorphic columns)

        return $tables;
    }

    /**
     * Get pivot table mappings
     */
    private function getPivotTables(): array
    {
        return [
            'bank_user' => 'user_id',
            'admin_user' => 'user_id',
            'organization_user' => 'user_id',
        ];
    }

    /**
     * Check if a table exists
     */
    private function tableExists(string $tableName): bool
    {
        try {
            DB::table($tableName)->limit(1)->count();
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Validate if user can be safely migrated
     */
    private function validateUserForMigration(User $user): array
    {
        $blockingErrors = [];
        $warnings = [];

        // BLOCKING ERRORS - Migration cannot proceed

        // Check if an organization with the same name already exists
        if (Organization::where('name', $user->name)->exists()) {
            $blockingErrors[] = "An Organization with name '{$user->name}' already exists";
        }

        // Check if an organization with the same email already exists
        if (Organization::where('email', $user->email)->exists()) {
            $blockingErrors[] = "An Organization with email '{$user->email}' already exists";
        }

        // Check if user is currently online (has recent presence)
        try {
            if (method_exists($user, 'isOnline') && $user->isOnline()) {
                $blockingErrors[] = "User is currently online - wait for them to go offline before migrating";
            }
        } catch (\Exception $e) {
            // Skip online check if presence system is not available
        }

        // WARNINGS - Migration can proceed with confirmation

        // Check if user is a super admin or critical system user
        if ($user->hasRole('Super Admin') || $user->hasRole('super-admin')) {
            $warnings[] = "User has Super Admin role - all admin privileges will be removed during migration";
        }

        // Check if user has critical system permissions
        $criticalPermissions = ['manage system', 'manage users', 'super-admin'];
        foreach ($criticalPermissions as $permission) {
            if ($user->can($permission)) {
                $warnings[] = "User has critical permission '{$permission}' - all admin permissions will be removed during migration";
                break;
            }
        }

        // Check if user has active two-factor authentication
        if (!empty($user->two_factor_secret)) {
            $warnings[] = "User has two-factor authentication enabled - this will be lost during migration";
        }

        // ORGANIZATION CONFLICTS - Separate from general warnings
        $organizationConflicts = [];

        // Check if user is already managing banks
        if ($user->banksManaged()->count() > 0) {
            $organizationConflicts[] = "User is managing " . $user->banksManaged()->count() . " bank(s). After the migration this will not be possible any more.";
        }

        // Check if user is already managing organizations
        if ($user->organizations()->count() > 0) {
            $organizationConflicts[] = "User is managing " . $user->organizations()->count() . " organization(s). After the migration this will not be possible any more.";
        }

        return [
            'blocking_errors' => $blockingErrors,
            'warnings' => $warnings,
            'organization_conflicts' => $organizationConflicts
        ];
    }

    /**
     * Remove admin relationships and roles before migration
     */
    private function removeAdminRelationshipsAndRoles(User $user): void
    {
        $this->info('Removing admin relationships and roles...');

        // Remove admin roles using Spatie method
        $adminRoles = ['admin', 'super-admin', 'Admin', 'Super Admin'];
        $rolesRemoved = [];

        foreach ($adminRoles as $roleName) {
            if ($user->hasRole($roleName)) {
                $user->removeRole($roleName);
                $rolesRemoved[] = $roleName;
            }
        }

        if (!empty($rolesRemoved)) {
            $this->line('   Removed roles: ' . implode(', ', $rolesRemoved));
        }

        // Remove admin relationships (many-to-many)
        $adminCount = $user->admins()->count();
        if ($adminCount > 0) {
            $user->admins()->detach();
            $this->line("   Removed {$adminCount} admin relationships");
        }

        // Remove bank management relationships
        $bankCount = $user->banksManaged()->count();
        if ($bankCount > 0) {
            $bankNames = $user->banksManaged()->pluck('name')->toArray();
            $user->banksManaged()->detach(); // Un-associate all managed banks
            $this->line("   Removed management of {$bankCount} bank(s): " . implode(', ', $bankNames));
        }

        // Remove organization management relationships
        $organizationCount = $user->organizations()->count();
        if ($organizationCount > 0) {
            $orgNames = $user->organizations()->pluck('name')->toArray();
            $user->organizations()->detach(); // Un-associate all managed organizations
            $this->line("   Removed management of {$organizationCount} organization(s): " . implode(', ', $orgNames));
        }

        if (empty($rolesRemoved) && $adminCount === 0 && $bankCount === 0 && $organizationCount === 0) {
            $this->line('   No admin relationships or roles to remove');
        }
    }

    /**
     * Delete User and cleanup all remaining relationships
     */
    private function deleteUserAndRelationships(User $user, Organization $organization): void
    {
        $this->info('Deleting User and cleaning up relationships...');

        // Step 1: Verify critical data was migrated
        $this->verifyMigrationCompleteness($user, $organization);

        // Step 2: Clean up pivot table relationships that weren't migrated
        $this->cleanupPivotRelationships($user);

        // Step 3: Clean up remaining foreign key references
        $this->cleanupForeignKeyReferences($user);

        // Step 4: Delete the User model
        $userId = $user->id;
        $userName = $user->name;

        $user->delete();

        $this->line("   Deleted User '{$userName}' (ID: {$userId})");

        // Step 5: Verify complete deletion
        $this->verifyUserDeletion($userId);
    }

    /**
     * Verify that critical data was successfully migrated
     */
    private function verifyMigrationCompleteness(User $user, Organization $organization): void
    {
        // Check that accounts were transferred
        $userAccounts = $user->accounts()->count();
        $orgAccounts = $organization->accounts()->count();

        if ($userAccounts > 0) {
            throw new \Exception("User still has {$userAccounts} accounts - migration incomplete");
        }

        if ($orgAccounts === 0) {
            $this->line("   Organization has no accounts - this may be expected");
        }

        $this->line("   Migration verification passed");
    }

    /**
     * Clean up pivot table relationships
     */
    private function cleanupPivotRelationships(User $user): void
    {
        $cleanupTables = [
            'organization_user' => 'user_id',
            'bank_user' => 'user_id'
            // admin_user is already handled in removeAdminRelationshipsAndRoles()
        ];

        foreach ($cleanupTables as $table => $column) {
            if ($this->tableExists($table)) {
                $count = DB::table($table)->where($column, $user->id)->count();
                if ($count > 0) {
                    DB::table($table)->where($column, $user->id)->delete();
                    $this->line("   Cleaned up {$table}: {$count} records deleted");
                }
            }
        }

        // Clean up Spatie permission pivot tables
        $permissionTables = [
            'model_has_roles' => ['model_type' => 'App\Models\User', 'model_id' => $user->id],
            'model_has_permissions' => ['model_type' => 'App\Models\User', 'model_id' => $user->id]
        ];

        foreach ($permissionTables as $table => $conditions) {
            if ($this->tableExists($table)) {
                $count = DB::table($table)->where($conditions)->count();
                if ($count > 0) {
                    DB::table($table)->where($conditions)->delete();
                    $this->line("   Cleaned up {$table}: {$count} records deleted");
                }
            }
        }
    }

    /**
     * Clean up foreign key references
     */
    private function cleanupForeignKeyReferences(User $user): void
    {
        // Clean up activity logs where User is the causer (not subject - those are audit trail)
        if ($this->tableExists('activity_log')) {
            $count = DB::table('activity_log')
                ->where('causer_type', 'App\Models\User')
                ->where('causer_id', $user->id)
                ->count();

            if ($count > 0) {
                // Set causer to null instead of deleting logs for audit trail
                DB::table('activity_log')
                    ->where('causer_type', 'App\Models\User')
                    ->where('causer_id', $user->id)
                    ->update([
                        'causer_type' => null,
                        'causer_id' => null
                    ]);
                $this->line("   Cleaned up activity_log causers: {$count} records updated");
            }
        }

        // Love package cleanup is handled by updateLoveRelationships() method
        // No additional cleanup needed as we're updating types, not deleting records

        // Clean up any remaining chat/messaging relationships
        $chatTables = ['chat_participants', 'chat_messages'];
        foreach ($chatTables as $table) {
            if ($this->tableExists($table)) {
                $userColumn = $table === 'chat_participants' ? 'user_id' : 'sender_id';
                $count = DB::table($table)->where($userColumn, $user->id)->count();

                if ($count > 0) {
                    if ($table === 'chat_messages') {
                        // For messages, mark as deleted rather than removing for chat history
                        DB::table($table)
                            ->where($userColumn, $user->id)
                            ->update(['sender_id' => null, 'deleted_at' => now()]);
                        $this->line("   Cleaned up {$table}: {$count} records marked as deleted");
                    } else {
                        DB::table($table)->where($userColumn, $user->id)->delete();
                        $this->line("   Cleaned up {$table}: {$count} records deleted");
                    }
                }
            }
        }
    }

    /**
     * Verify User was completely deleted
     */
    private function verifyUserDeletion(int $userId): void
    {
        // Check that User record is gone
        if (User::find($userId)) {
            throw new \Exception("User deletion failed - User {$userId} still exists");
        }

        // Check for any remaining references in key tables
        $checkTables = [
            'organization_user' => 'user_id',
            'bank_user' => 'user_id',
            'admin_user' => 'user_id'
        ];

        foreach ($checkTables as $table => $column) {
            if ($this->tableExists($table)) {
                $remaining = DB::table($table)->where($column, $userId)->count();
                if ($remaining > 0) {
                    $this->line("   Warning: {$remaining} records remain in {$table}");
                }
            }
        }

        $this->line("   User deletion verification completed");
    }
}
