<?php

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;

uses(RefreshDatabase::class);

describe('CreateInitialAdmin Command', function () {

    it('creates an admin user with provided email and name', function () {
        $this->artisan('authentikate:create-admin', [
            '--email' => 'admin@test.com',
            '--name' => 'Test Admin'
        ])
            ->expectsOutput('✅ Initial admin user created successfully!')
            ->expectsOutput('📧 Email:    admin@test.com')
            ->expectsOutputToContain('🔑 Password:')
            ->expectsOutput('⚠️  Please log in and change your password immediately!')
            ->assertExitCode(0);

        // Verify user was created in database
        $this->assertDatabaseHas('users', [
            'email' => 'admin@test.com',
            'name' => 'Test Admin',
            'is_admin' => true,
        ]);

        $user = User::where('email', 'admin@test.com')->first();
        expect($user)->not()->toBeNull();
        expect($user->password)->not()->toBeEmpty();
    });

    it('prompts for email and name when not provided', function () {
        $this->artisan('authentikate:create-admin')
            ->expectsQuestion('Admin email address', 'prompted@test.com')
            ->expectsQuestion('Admin name', 'Prompted Admin')
            ->expectsOutput('✅ Initial admin user created successfully!')
            ->assertExitCode(0);

        $user = User::where('email', 'prompted@test.com')->first();
        expect($user)->not()->toBeNull();
        expect($user->name)->toBe('Prompted Admin');
        expect($user->is_admin)->toBe(true);
    });

    it('prevents creating admin when one already exists', function () {
        User::factory()->create(['is_admin' => true]);

        $this->artisan('authentikate:create-admin', [
            '--email' => 'new@test.com',
            '--name' => 'New Admin'
        ])
            ->expectsOutput('Admin users already exist! Use --force to create anyway.')
            ->assertExitCode(0);

        expect(User::where('email', 'new@test.com')->exists())->toBe(false);
    });

    it('creates admin when forced even if one exists', function () {
        User::factory()->create(['is_admin' => true]);

        $this->artisan('authentikate:create-admin', [
            '--email' => 'forced@test.com',
            '--name' => 'Forced Admin',
            '--force' => true
        ])
            ->expectsOutput('✅ Initial admin user created successfully!')
            ->assertExitCode(0);

        expect(User::where('email', 'forced@test.com')->exists())->toBe(true);
    });

    it('validates email format', function () {
        $this->artisan('authentikate:create-admin', [
            '--email' => 'invalid-email',
            '--name' => 'Test Admin'
        ])
            ->expectsOutput('Invalid email address format.')
            ->assertExitCode(0);
    });

    it('prevents duplicate email addresses', function () {
        User::factory()->create(['email' => 'existing@test.com']);

        $this->artisan('authentikate:create-admin', [
            '--email' => 'existing@test.com',
            '--name' => 'Test Admin',
            '--force' => true
        ])
            ->expectsOutput("A user with email 'existing@test.com' already exists.")
            ->assertExitCode(0);
    });

    it('generates a secure password with mixed characters', function () {
        $this->artisan('authentikate:create-admin', [
            '--email' => 'secure@test.com',
            '--name' => 'Secure Admin'
        ]);

        $user = User::where('email', 'secure@test.com')->first();
        expect($user)->not()->toBeNull();

        // The password should be hashed
        expect($user->password)->not()->toBeEmpty();
        expect(strlen($user->password))->toBeGreaterThan(50); // Hashed passwords are long
    });

    it('uses default values when interactive prompts accept defaults', function () {
        $this->artisan('authentikate:create-admin')
            ->expectsQuestion('Admin email address', 'admin@authentikate.local')
            ->expectsQuestion('Admin name', 'Administrator')
            ->expectsOutput('✅ Initial admin user created successfully!')
            ->assertExitCode(0);

        $user = User::where('email', 'admin@authentikate.local')->first();
        expect($user)->not()->toBeNull();
        expect($user->name)->toBe('Administrator');
    });
});
