<?php

namespace Tests\Feature;

use App\Imports\Blog\BlogAuthorResolver;
use Mtc\MercuryDataModels\Tenant;
use Mtc\MercuryDataModels\User;
use Tests\DatabaseTestCase;

class BlogAuthorResolverTest extends DatabaseTestCase
{
    public function testReturnsNullForEmptyName(): void
    {
        $resolver = new BlogAuthorResolver();

        $this->assertNull($resolver->resolveByName(null));
        $this->assertNull($resolver->resolveByName(''));
        $this->assertNull($resolver->resolveByName('   '));
    }

    public function testCreatesLockedUserAttachedToTenantWhenNoMatchExists(): void
    {
        $resolver = new BlogAuthorResolver();

        $authorId = $resolver->resolveByName('Jane Smith');

        $this->assertNotNull($authorId);

        $user = User::find($authorId);
        $this->assertNotNull($user);
        $this->assertSame('Jane Smith', $user->name);
        $this->assertTrue($user->is_locked);
        $this->assertStringEndsWith('@noreply.getautonomy.co.uk', $user->email);
        $this->assertTrue($user->tenants()->where('tenants.id', tenant('id'))->exists());
        $this->assertCount(0, $user->roles);
    }

    public function testReusesSameUserOnSubsequentCalls(): void
    {
        $resolver = new BlogAuthorResolver();

        $firstId = $resolver->resolveByName('Jane Smith');
        $secondId = $resolver->resolveByName('Jane Smith');

        $this->assertSame($firstId, $secondId);
        $this->assertSame(1, User::where('name', 'Jane Smith')->count());
    }

    public function testMatchIsCaseInsensitive(): void
    {
        $resolver = new BlogAuthorResolver();

        $firstId = $resolver->resolveByName('Jane Smith');
        $secondId = $resolver->resolveByName('JANE SMITH');
        $thirdId = $resolver->resolveByName('  jane smith  ');

        $this->assertSame($firstId, $secondId);
        $this->assertSame($firstId, $thirdId);
    }

    public function testMatchesExistingAdminUserOnTenantRegardlessOfLockState(): void
    {
        $admin = User::factory()->create(['name' => 'Jane Smith', 'is_locked' => false]);
        $admin->tenants()->attach(tenant('id'));

        $resolver = new BlogAuthorResolver();

        $authorId = $resolver->resolveByName('Jane Smith');

        $this->assertSame($admin->id, $authorId);
        $this->assertSame(1, User::where('name', 'Jane Smith')->count());
    }

    public function testDoesNotMatchUserOnAnotherTenant(): void
    {
        $otherTenant = Tenant::factory()->create();
        $otherTenantUser = User::factory()->create(['name' => 'Jane Smith']);
        $otherTenantUser->tenants()->attach($otherTenant->id);

        $resolver = new BlogAuthorResolver();

        $authorId = $resolver->resolveByName('Jane Smith');

        $this->assertNotSame($otherTenantUser->id, $authorId);
        $this->assertSame(2, User::where('name', 'Jane Smith')->count());
    }
}
