<?php

declare(strict_types=1);

use App\Models\Artwork;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;

uses(RefreshDatabase::class);

it('passes when every artwork has a matching user', function (): void {
    Artwork::factory()->count(3)->create();

    $code = Artisan::call('artworks:check-user-refs', [
        '--chunk' => 2,
        '--show-missing' => 5,
    ]);

    $output = Artisan::output();
    file_put_contents(storage_path('logs/check-artwork-user-refs-test-output.log'), $output);

    expect($code)->toBe(0)
        ->and($output)->toContain('Checked 3 artworks: 3 valid, 0 missing user references, 0 null user_id values.')
        ->and($output)->toContain('No missing user references found in artworks.user_id.');
});

it('fails and reports orphaned artwork user references', function (): void {
    $validArtwork = Artwork::factory()->create();
    $orphanedArtwork = Artwork::factory()->create();

    DB::table('artworks')
        ->where('id', $orphanedArtwork->id)
        ->update(['user_id' => 999999]);

    $code = Artisan::call('artworks:check-user-refs', [
        '--chunk' => 1,
        '--show-missing' => 5,
    ]);

    $output = Artisan::output();

    expect($validArtwork->fresh())->not->toBeNull()
        ->and($code)->toBe(1)
        ->and($output)->toContain('Checked 2 artworks: 1 valid, 1 missing user references, 0 null user_id values.')
        ->and($output)->toContain('Found artworks with missing user references.')
        ->and($output)->toContain((string) $orphanedArtwork->id)
        ->and($output)->toContain('999999');
});

it('can copy missing referenced users from the legacy users table by the same id', function (): void {
    $legacyUserId = 777;
    $artwork = Artwork::factory()->create();

    DB::table('artworks')
        ->where('id', $artwork->id)
        ->update(['user_id' => $legacyUserId]);

    config()->set('database.connections.legacy', config('database.connections.' . config('database.default')));
    DB::purge('legacy');

    Schema::connection('legacy')->dropIfExists('legacy_users');
    Schema::connection('legacy')->create('legacy_users', function (Blueprint $table): void {
        $table->unsignedBigInteger('user_id')->primary();
        $table->string('uname')->nullable();
        $table->string('real_name')->nullable();
        $table->string('email')->nullable();
        $table->unsignedTinyInteger('active')->default(1);
        $table->timestamp('joinDate')->nullable();
        $table->timestamp('LastVisit')->nullable();
        $table->string('country')->nullable();
        $table->string('country_code', 2)->nullable();
        $table->string('web')->nullable();
        $table->text('about_me')->nullable();
        $table->text('description')->nullable();
        $table->string('gender', 16)->nullable();
    });

    DB::connection('legacy')->table('legacy_users')->insert([
        'user_id' => $legacyUserId,
        'uname' => 'legacy_artist',
        'real_name' => 'Legacy Artist',
        'email' => 'legacy.artist@example.test',
        'active' => 1,
        'joinDate' => '2020-01-02 03:04:05',
        'LastVisit' => '2025-01-05 06:07:08',
        'country' => 'Finland',
        'country_code' => 'FI',
        'web' => 'legacy.example.test',
        'about_me' => 'Imported from legacy.',
        'gender' => 'F',
    ]);

    $code = Artisan::call('artworks:check-user-refs', [
        '--chunk' => 1,
        '--show-missing' => 5,
        '--copy-missing-from-legacy' => true,
        '--legacy-users-table' => 'legacy_users',
    ]);

    $output = Artisan::output();
    file_put_contents(storage_path('logs/check-artwork-user-refs-copy-test-output.log'), $output);

    expect($code)->toBe(0)
        ->and(DB::table('users')->where('id', $legacyUserId)->exists())->toBeTrue()
        ->and(DB::table('user_profiles')->where('user_id', $legacyUserId)->value('country_code'))->toBe('FI')
        ->and($output)->toContain('[copied] imported legacy user #777 username=@legacy_artist name="Legacy Artist" email=<legacy.artist@example.test>')
        ->and($output)->toContain('Checked 1 artworks: 1 valid, 0 missing user references, 0 null user_id values.')
        ->and($output)->toContain('Legacy copy summary: requested 1 users, copied 1, would copy 0, conflicts 0, not found in legacy 0, errors 0.')
        ->and($output)->toContain('Copied or would-copy user ids: 777');

    Schema::connection('legacy')->dropIfExists('legacy_users');
});

it('shows dry run copy details for legacy imports', function (): void {
    $legacyUserId = 778;
    $artwork = Artwork::factory()->create();

    DB::table('artworks')
        ->where('id', $artwork->id)
        ->update(['user_id' => $legacyUserId]);

    config()->set('database.connections.legacy', config('database.connections.' . config('database.default')));
    DB::purge('legacy');

    Schema::connection('legacy')->dropIfExists('legacy_users');
    Schema::connection('legacy')->create('legacy_users', function (Blueprint $table): void {
        $table->unsignedBigInteger('user_id')->primary();
        $table->string('uname')->nullable();
        $table->string('real_name')->nullable();
        $table->string('email')->nullable();
        $table->unsignedTinyInteger('active')->default(1);
        $table->timestamp('joinDate')->nullable();
        $table->timestamp('LastVisit')->nullable();
        $table->string('country')->nullable();
        $table->string('country_code', 2)->nullable();
        $table->string('web')->nullable();
        $table->text('about_me')->nullable();
        $table->text('description')->nullable();
        $table->string('gender', 16)->nullable();
    });

    DB::connection('legacy')->table('legacy_users')->insert([
        'user_id' => $legacyUserId,
        'uname' => 'legacy_preview',
        'real_name' => 'Legacy Preview',
        'email' => 'legacy.preview@example.test',
        'active' => 1,
    ]);

    $code = Artisan::call('artworks:check-user-refs', [
        '--chunk' => 1,
        '--show-missing' => 5,
        '--copy-missing-from-legacy' => true,
        '--dry-run-copy' => true,
        '--legacy-users-table' => 'legacy_users',
    ]);

    $output = Artisan::output();

    expect($code)->toBe(1)
        ->and(DB::table('users')->where('id', $legacyUserId)->exists())->toBeFalse()
        ->and($output)->toContain('[dry-run] would import legacy user #778 username=@legacy_preview name="Legacy Preview" email=<legacy.preview@example.test>')
        ->and($output)->toContain('Legacy copy summary: requested 1 users, copied 0, would copy 1, conflicts 0, not found in legacy 0, errors 0.');

    Schema::connection('legacy')->dropIfExists('legacy_users');
});