<?php

namespace Tests\Feature;

use App\Enums\UserRole;
use App\Models\Business;
use App\Models\Language;
use App\Models\Translation;
use App\Models\User;
use App\Services\Localization\LanguageService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LanguageTranslationManagementTest extends TestCase
{
    use RefreshDatabase;

    public function test_seeded_languages_have_required_directions_and_arabic_translations(): void
    {
        app(LanguageService::class)->ensureDefaults(fillMissingTranslations: true);

        $english = Language::query()->where('code', 'en')->firstOrFail();
        $arabic = Language::query()->where('code', 'ar')->firstOrFail();
        $urdu = Language::query()->where('code', 'ur')->firstOrFail();

        $this->assertSame('ltr', $english->direction);
        $this->assertTrue($english->is_default);
        $this->assertSame('rtl', $arabic->direction);
        $this->assertSame('rtl', $urdu->direction);
        $this->assertSame('العربية', $arabic->native_name);
        $this->assertSame(0, Translation::query()->where('language_id', $arabic->id)->where('is_missing', true)->count());

        $this->assertDatabaseHas('translations', [
            'language_id' => $arabic->id,
            'module' => 'settings',
            'translation_key' => 'save_changes',
            'translated_text' => 'حفظ التغييرات',
        ]);
        $this->assertDatabaseHas('translations', [
            'language_id' => $arabic->id,
            'module' => 'public_booking',
            'translation_key' => 'select_service',
            'translated_text' => 'اختر الخدمة',
        ]);
    }

    public function test_business_owner_can_create_toggle_and_set_default_language(): void
    {
        [$owner] = $this->ownerWithBusiness();
        app(LanguageService::class)->ensureDefaults(fillMissingTranslations: true);

        $this->actingAs($owner)
            ->post(route('admin.settings.languages.store'), [
                'name' => 'French',
                'native_name' => 'Francais',
                'code' => 'fr',
                'direction' => 'ltr',
                'flag_icon' => 'FR',
                'is_active' => '1',
            ])
            ->assertRedirect(route('admin.settings.languages.index'));

        $french = Language::query()->where('code', 'fr')->firstOrFail();

        $this->assertDatabaseHas('languages', [
            'code' => 'fr',
            'name' => 'French',
            'direction' => 'ltr',
            'is_active' => true,
        ]);
        $this->assertGreaterThan(0, $french->translations()->count());

        $this->actingAs($owner)
            ->patch(route('admin.settings.languages.toggle', $french))
            ->assertRedirect(route('admin.settings.languages.index'));

        $this->assertFalse($french->refresh()->is_active);

        $this->actingAs($owner)
            ->patch(route('admin.settings.languages.default', $french))
            ->assertRedirect(route('admin.settings.languages.index'));

        $this->assertTrue($french->refresh()->is_default);
        $this->assertTrue($french->is_active);
        $this->assertFalse(Language::query()->where('code', 'en')->firstOrFail()->is_default);
    }

    public function test_translation_values_can_be_edited(): void
    {
        [$owner] = $this->ownerWithBusiness();
        app(LanguageService::class)->ensureDefaults(fillMissingTranslations: true);

        $arabic = Language::query()->where('code', 'ar')->firstOrFail();
        $translation = Translation::query()
            ->where('language_id', $arabic->id)
            ->where('module', 'dashboard')
            ->where('translation_key', 'revenue')
            ->firstOrFail();

        $this->actingAs($owner)
            ->post(route('admin.settings.translations.update'), [
                'translations' => [
                    $translation->id => 'إيرادات محدثة',
                ],
            ])
            ->assertRedirect();

        $this->assertDatabaseHas('translations', [
            'id' => $translation->id,
            'translated_text' => 'إيرادات محدثة',
            'is_missing' => false,
        ]);
    }

    public function test_translation_export_and_import_json(): void
    {
        [$owner] = $this->ownerWithBusiness();
        app(LanguageService::class)->ensureDefaults(fillMissingTranslations: true);
        $arabic = Language::query()->where('code', 'ar')->firstOrFail();

        $export = $this->actingAs($owner)
            ->get(route('admin.settings.translations.export', [
                'language_id' => $arabic->id,
                'module' => 'dashboard',
            ]))
            ->assertOk()
            ->assertHeader('Content-Type', 'application/json; charset=UTF-8');

        $this->assertStringContainsString('إجمالي الحجوزات', $export->getContent());

        $payload = [
            'locale' => 'ar',
            'direction' => 'rtl',
            'translations' => [
                'dashboard' => [
                    'revenue' => 'إيرادات مستوردة',
                ],
            ],
        ];

        $this->actingAs($owner)
            ->post(route('admin.settings.translations.import'), [
                'language_id' => $arabic->id,
                'json_payload' => json_encode($payload, JSON_UNESCAPED_UNICODE),
            ])
            ->assertRedirect(route('admin.settings.translations', ['language_id' => $arabic->id]));

        $this->assertDatabaseHas('translations', [
            'language_id' => $arabic->id,
            'module' => 'dashboard',
            'translation_key' => 'revenue',
            'translated_text' => 'إيرادات مستوردة',
        ]);
    }

    public function test_active_language_middleware_applies_rtl_to_admin_auth_and_public_layouts(): void
    {
        [$owner, $business] = $this->ownerWithBusiness();
        app(LanguageService::class)->ensureDefaults(fillMissingTranslations: true);

        $this->get('/login?lang=ar')
            ->assertOk()
            ->assertSee('<html lang="ar" dir="rtl">', false);

        $this->get(route('public.booking.profile', ['business_slug' => $business->slug, 'lang' => 'ar']))
            ->assertOk()
            ->assertSee('<html lang="ar" dir="rtl">', false);

        $this->actingAs($owner)
            ->get(route('admin.dashboard', ['lang' => 'ar']))
            ->assertOk()
            ->assertSee('<html lang="ar" dir="rtl">', false);
    }

    private function ownerWithBusiness(string $email = 'owner@booklio.test'): array
    {
        $owner = User::factory()->create([
            'email' => $email,
            'role' => UserRole::BusinessOwner->value,
        ]);
        $business = Business::factory()->create([
            'owner_id' => $owner->id,
            'status' => 'active',
        ]);

        return [$owner, $business];
    }
}
