<?php

namespace App\Console\Commands;

use App\Models\MailingBounce;
use App\Models\User;
use App\Models\Organization;
use Illuminate\Console\Command;

class TestBounceSystem extends Command
{
    /**
     * The name and signature of the console command.
     */
    protected $signature = 'test:bounce-system
                            {--email= : Email to test (default: creates test emails)}
                            {--scenario= : Test scenario: single, threshold-verification, threshold-suppression, multiple}';

    /**
     * The console command description.
     */
    protected $description = 'Test the bounce handling system with simulated bounces';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $scenario = $this->option('scenario') ?: 'single';
        $email = $this->option('email');

        switch ($scenario) {
            case 'single':
                $this->testSingleBounce($email);
                break;
            case 'threshold-verification':
                $this->testVerificationThreshold($email);
                break;
            case 'threshold-suppression':
                $this->testSuppressionThreshold($email);
                break;
            case 'multiple':
                $this->testMultipleEmails();
                break;
            default:
                $this->error("Unknown scenario: {$scenario}");
                $this->info("Available scenarios: single, threshold-verification, threshold-suppression, multiple");
                return 1;
        }

        return 0;
    }

    /**
     * Test a single bounce (should not trigger any thresholds)
     */
    protected function testSingleBounce(?string $email): void
    {
        $testEmail = $email ?: 'test-single@example.com';

        $this->info("🧪 Testing Single Bounce for: {$testEmail}");

        // Create a test user with verified email
        $this->createTestUser($testEmail);

        // Record a single hard bounce with definitive pattern
        $bounce = MailingBounce::recordBounce(
            $testEmail,
            'hard',
            'user unknown - mailbox does not exist'
        );

        $this->line("✅ Created bounce record ID: {$bounce->id}");

        // Check the results
        $stats = MailingBounce::getBounceStats($testEmail);
        $this->displayResults($testEmail, $stats);
    }

    /**
     * Test verification threshold (2 bounces)
     */
    protected function testVerificationThreshold(?string $email): void
    {
        $testEmail = $email ?: 'test-verification@example.com';

        $this->info("🧪 Testing Verification Reset Threshold for: {$testEmail}");

        // Create test user with verified email
        $user = $this->createTestUser($testEmail);
        $this->line("📧 Created test user with verified email: {$user->email_verified_at}");

        // Record first bounce with exact pattern from config
        $this->line("1️⃣ Recording first hard bounce...");
        MailingBounce::recordBounce($testEmail, 'hard', 'user unknown - definitive bounce');

        $user->refresh();
        $this->line("   User email_verified_at: " . ($user->email_verified_at ?: 'NULL'));

        // Record second bounce (should trigger verification reset)
        $this->line("2️⃣ Recording second hard bounce (should reset verification)...");
        MailingBounce::recordBounce($testEmail, 'hard', 'mailbox unavailable - permanent failure');

        $user->refresh();
        $this->line("   User email_verified_at: " . ($user->email_verified_at ?: 'NULL'));

        // Check results
        $stats = MailingBounce::getBounceStats($testEmail);
        $this->displayResults($testEmail, $stats);

        if (!$user->email_verified_at) {
            $this->info("✅ SUCCESS: Email verification was reset!");
        } else {
            $this->error("❌ FAILED: Email verification was NOT reset!");
        }
    }

    /**
     * Test suppression threshold (3 bounces)
     */
    protected function testSuppressionThreshold(?string $email): void
    {
        $testEmail = $email ?: 'test-suppression@example.com';

        $this->info("🧪 Testing Suppression Threshold for: {$testEmail}");

        // Create test user
        $user = $this->createTestUser($testEmail);

        // Record three bounces
        for ($i = 1; $i <= 3; $i++) {
            $this->line("{$i}️⃣ Recording hard bounce #{$i}...");
            MailingBounce::recordBounce($testEmail, 'hard', "user unknown - attempt {$i}");

            $user->refresh();
            $isSuppressed = MailingBounce::isSuppressed($testEmail);

            $this->line("   Suppressed: " . ($isSuppressed ? 'YES' : 'NO'));
            $this->line("   Email verified: " . ($user->email_verified_at ? 'YES' : 'NO'));
        }

        // Check final results
        $stats = MailingBounce::getBounceStats($testEmail);
        $this->displayResults($testEmail, $stats);

        if ($stats['is_suppressed']) {
            $this->info("✅ SUCCESS: Email was suppressed after 3 bounces!");
        } else {
            $this->error("❌ FAILED: Email was NOT suppressed!");
        }
    }

    /**
     * Test multiple emails with different scenarios
     */
    protected function testMultipleEmails(): void
    {
        $this->info("🧪 Testing Multiple Email Scenarios");

        $scenarios = [
            'no-bounce@example.com' => 0,
            'one-bounce@example.com' => 1,
            'verification-reset@example.com' => 2,
            'suppressed@example.com' => 3,
            'over-threshold@example.com' => 5
        ];

        foreach ($scenarios as $email => $bounceCount) {
            $this->line("Setting up {$email} with {$bounceCount} bounces...");

            $this->createTestUser($email);

            for ($i = 1; $i <= $bounceCount; $i++) {
                MailingBounce::recordBounce($email, 'hard', "user unknown - bounce {$i}");
            }
        }

        $this->info("\n📊 Results Summary:");
        foreach ($scenarios as $email => $expectedBounces) {
            $stats = MailingBounce::getBounceStats($email);
            $user = User::where('email', $email)->first();

            $this->line("📧 {$email}:");
            $this->line("   Hard bounces: {$stats['recent_hard_bounces']}");
            $this->line("   Suppressed: " . ($stats['is_suppressed'] ? 'YES' : 'NO'));
            $this->line("   Verified: " . ($user && $user->email_verified_at ? 'YES' : 'NO'));
        }
    }

    /**
     * Create a test user with verified email
     */
    protected function createTestUser(string $email): User
    {
        // Remove existing test user if any
        User::where('email', $email)->delete();

        $user = User::create([
            'name' => 'Test User ' . substr($email, 0, strpos($email, '@')),
            'email' => $email,
            'password' => bcrypt('password'),
        ]);

        // Use forceFill since email_verified_at isn't in fillable
        $user->forceFill(['email_verified_at' => now()])->save();

        return $user;
    }

    /**
     * Display test results
     */
    protected function displayResults(string $email, array $stats): void
    {
        $this->info("\n📊 Test Results for {$email}:");
        $this->line("Total bounces: {$stats['total_bounces']}");
        $this->line("Recent hard bounces: {$stats['recent_hard_bounces']}");
        $this->line("Is suppressed: " . ($stats['is_suppressed'] ? 'YES' : 'NO'));

        $user = User::where('email', $email)->first();
        if ($user) {
            $this->line("Email verified: " . ($user->email_verified_at ? 'YES' : 'NO'));
        }

        $this->line("");
    }
}