<?php

namespace Tests\Feature;

use App\Models\Language;
use App\Models\LanguageTranslation;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LanguageManagementTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_system_admin_can_add_language_and_manage_translations(): void
    {
        $admin = User::query()->where('email', 'admin@microfinance.local')->firstOrFail();

        $response = $this->actingAs($admin)->post(route('admin.languages.store'), [
            'name' => 'Swahili',
            'native_name' => 'Kiswahili',
            'code' => 'sw',
            'direction' => 'ltr',
            'is_active' => '1',
        ]);

        $language = Language::query()->where('code', 'sw')->firstOrFail();

        $response->assertRedirect(route('admin.languages.translations', $language));
        $this->assertTrue($language->is_active);
        $this->assertFalse($language->is_default);

        $this->actingAs($admin)
            ->put(route('admin.languages.translations.update', $language), [
                'translations' => [
                    'ui.dashboard' => 'Dashibodi',
                    'ui.customers' => 'Wateja',
                ],
            ])
            ->assertRedirect();

        $this->assertDatabaseHas('language_translations', [
            'language_id' => $language->id,
            'key' => 'ui.dashboard',
            'value' => 'Dashibodi',
        ]);
    }

    public function test_language_list_uses_table_actions_and_dedicated_edit_page(): void
    {
        $admin = User::query()->where('email', 'admin@microfinance.local')->firstOrFail();
        $swahili = Language::query()->create([
            'name' => 'Swahili',
            'native_name' => 'Kiswahili',
            'code' => 'sw',
            'direction' => 'ltr',
            'is_active' => true,
            'is_default' => false,
        ]);

        $index = $this->actingAs($admin)->get(route('admin.languages.index'));

        $index->assertOk();
        $index->assertSee('languages-table', false);
        $index->assertSee(route('admin.languages.translations', $swahili), false);
        $index->assertSee(route('admin.languages.edit', $swahili), false);
        $index->assertSee('Manage translations');
        $index->assertSee('Edit');
        $index->assertSee('Make default');

        $edit = $this->actingAs($admin)->get(route('admin.languages.edit', $swahili));
        $edit->assertOk();
        $edit->assertSee('Edit language');
        $edit->assertSee('Kiswahili');

        $this->actingAs($admin)
            ->put(route('admin.languages.update', $swahili), [
                'name' => 'Swahili Updated',
                'native_name' => 'Kiswahili',
                'code' => 'sw',
                'direction' => 'ltr',
                'is_active' => '1',
            ])
            ->assertRedirect();

        $this->assertDatabaseHas('languages', [
            'id' => $swahili->id,
            'name' => 'Swahili Updated',
            'is_active' => true,
        ]);
    }

    public function test_user_can_switch_to_active_language_and_database_translation_is_rendered(): void
    {
        $admin = User::query()->where('email', 'admin@microfinance.local')->firstOrFail();
        $swahili = Language::query()->create([
            'name' => 'Swahili',
            'native_name' => 'Kiswahili',
            'code' => 'sw',
            'direction' => 'ltr',
            'is_active' => true,
            'is_default' => false,
        ]);

        LanguageTranslation::query()->create([
            'language_id' => $swahili->id,
            'key' => 'ui.dashboard',
            'value' => 'Dashibodi',
        ]);

        $this->actingAs($admin)
            ->post(route('locale.switch'), ['locale' => 'sw'])
            ->assertSessionHas('locale', 'sw');

        $response = $this->actingAs($admin)
            ->withSession(['locale' => 'sw'])
            ->get(route('admin.languages.index'));

        $response->assertOk();
        $response->assertSee('Dashibodi');
        $response->assertSee('lang="sw"', false);
    }

    public function test_default_language_cannot_be_deleted_and_new_default_is_forced_active(): void
    {
        $admin = User::query()->where('email', 'admin@microfinance.local')->firstOrFail();
        $english = Language::query()->where('is_default', true)->firstOrFail();
        $swahili = Language::query()->create([
            'name' => 'Swahili',
            'native_name' => 'Kiswahili',
            'code' => 'sw',
            'direction' => 'ltr',
            'is_active' => false,
            'is_default' => false,
        ]);

        $this->actingAs($admin)
            ->delete(route('admin.languages.destroy', $english))
            ->assertSessionHasErrors('language');

        $this->actingAs($admin)
            ->post(route('admin.languages.default', $swahili))
            ->assertRedirect();

        $this->assertDatabaseHas('languages', [
            'id' => $swahili->id,
            'is_default' => true,
            'is_active' => true,
        ]);
        $this->assertDatabaseHas('languages', [
            'id' => $english->id,
            'is_default' => false,
        ]);
    }

    public function test_inactive_language_cannot_be_selected(): void
    {
        $admin = User::query()->where('email', 'admin@microfinance.local')->firstOrFail();
        Language::query()->create([
            'name' => 'French',
            'native_name' => 'Français',
            'code' => 'fr',
            'direction' => 'ltr',
            'is_active' => false,
            'is_default' => false,
        ]);

        $this->actingAs($admin)
            ->post(route('locale.switch'), ['locale' => 'fr'])
            ->assertNotFound();
    }
}
