<?php

use App\Models\AdminLog;
use App\Models\Page;
use App\Models\User;
use Livewire\Volt\Volt;

beforeEach(function () {
    $this->admin = User::factory()->admin()->create();
    // Ensure test pages exist
    Page::factory()->terms()->create();
    Page::factory()->privacy()->create();
});

// ===========================================
// Admin Index Page Tests
// ===========================================

test('admin can view legal pages list', function () {
    $this->actingAs($this->admin)
        ->get(route('admin.pages.index'))
        ->assertOk()
        ->assertSee('Terms of Service')
        ->assertSee('Privacy Policy');
});

test('legal pages list shows both pages', function () {
    $this->actingAs($this->admin);

    $component = Volt::test('admin.pages.index');

    expect($component->viewData('pages')->count())->toBe(2);
});

// ===========================================
// Admin Edit Page Tests
// ===========================================

test('admin can view terms edit page', function () {
    $this->actingAs($this->admin)
        ->get(route('admin.pages.edit', 'terms'))
        ->assertOk();
});

test('admin can view privacy edit page', function () {
    $this->actingAs($this->admin)
        ->get(route('admin.pages.edit', 'privacy'))
        ->assertOk();
});

test('admin can edit terms of service in Arabic', function () {
    $page = Page::where('slug', 'terms')->first();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_ar', '<p>شروط الخدمة الجديدة</p>')
        ->call('save')
        ->assertHasNoErrors();

    expect($page->fresh()->content_ar)->toContain('شروط الخدمة الجديدة');
});

test('admin can edit terms of service in English', function () {
    $page = Page::where('slug', 'terms')->first();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_en', '<p>New terms content</p>')
        ->call('save')
        ->assertHasNoErrors();

    expect($page->fresh()->content_en)->toContain('New terms content');
});

test('admin can edit privacy policy in Arabic', function () {
    $page = Page::where('slug', 'privacy')->first();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'privacy'])
        ->set('content_ar', '<p>سياسة الخصوصية الجديدة</p>')
        ->call('save')
        ->assertHasNoErrors();

    expect($page->fresh()->content_ar)->toContain('سياسة الخصوصية الجديدة');
});

test('admin can edit privacy policy in English', function () {
    $page = Page::where('slug', 'privacy')->first();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'privacy'])
        ->set('content_en', '<p>New privacy policy</p>')
        ->call('save')
        ->assertHasNoErrors();

    expect($page->fresh()->content_en)->toContain('New privacy policy');
});

test('admin can preview page content', function () {
    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->assertSet('showPreview', false)
        ->call('togglePreview')
        ->assertSet('showPreview', true);
});

test('preview modal can be closed', function () {
    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->call('togglePreview')
        ->assertSet('showPreview', true)
        ->call('closePreview')
        ->assertSet('showPreview', false);
});

test('updated_at timestamp changes on save', function () {
    $page = Page::where('slug', 'terms')->first();
    $originalTimestamp = $page->updated_at;

    $this->travel(1)->minute();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_en', '<p>Updated content</p>')
        ->call('save');

    expect($page->fresh()->updated_at)->toBeGreaterThan($originalTimestamp);
});

test('html content is sanitized on save', function () {
    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_en', '<script>alert("xss")</script><p>Safe content</p>')
        ->call('save');

    $page = Page::where('slug', 'terms')->first();
    expect($page->content_en)->not->toContain('<script>');
    expect($page->content_en)->toContain('Safe content');
});

test('admin log created on page update', function () {
    $page = Page::where('slug', 'terms')->first();

    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_en', '<p>Updated content</p>')
        ->call('save');

    expect(AdminLog::where('action', 'update')
        ->where('target_type', 'page')
        ->where('target_id', $page->id)
        ->exists())->toBeTrue();
});

test('language tabs switch correctly', function () {
    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->assertSet('activeTab', 'ar')
        ->call('setTab', 'en')
        ->assertSet('activeTab', 'en')
        ->call('setTab', 'ar')
        ->assertSet('activeTab', 'ar');
});

test('empty content can be saved', function () {
    $this->actingAs($this->admin);

    Volt::test('admin.pages.edit', ['slug' => 'terms'])
        ->set('content_ar', '')
        ->set('content_en', '')
        ->call('save')
        ->assertHasNoErrors();

    $page = Page::where('slug', 'terms')->first();
    expect($page->content_ar)->toBe('');
    expect($page->content_en)->toBe('');
});

// ===========================================
// Public Page Tests
// ===========================================

test('public can view terms page', function () {
    Page::where('slug', 'terms')->update(['content_en' => '<p>Our terms</p>']);

    $this->withSession(['locale' => 'en'])
        ->get('/page/terms')
        ->assertOk()
        ->assertSee('Our terms');
});

test('public can view privacy page', function () {
    Page::where('slug', 'privacy')->update(['content_en' => '<p>Our privacy policy</p>']);

    $this->withSession(['locale' => 'en'])
        ->get('/page/privacy')
        ->assertOk()
        ->assertSee('Our privacy policy');
});

test('public page shows last updated timestamp', function () {
    $page = Page::where('slug', 'terms')->first();

    $this->get('/page/terms')
        ->assertOk()
        ->assertSee($page->updated_at->format('M d, Y'));
});

test('invalid page slug returns 404', function () {
    $this->get('/page/invalid-slug')
        ->assertNotFound();
});

test('legacy terms route redirects to new route', function () {
    $this->get('/terms')
        ->assertRedirect('/page/terms');
});

test('legacy privacy route redirects to new route', function () {
    $this->get('/privacy')
        ->assertRedirect('/page/privacy');
});

test('public page displays content in correct language based on locale', function () {
    Page::where('slug', 'terms')->update([
        'content_ar' => '<p>شروط الخدمة</p>',
        'content_en' => '<p>Terms of Service</p>',
    ]);

    // Test English
    $this->withSession(['locale' => 'en'])
        ->get('/page/terms')
        ->assertSee('Terms of Service');

    // Test Arabic
    $this->withSession(['locale' => 'ar'])
        ->get('/page/terms')
        ->assertSee('شروط الخدمة');
});

// ===========================================
// Authorization Tests
// ===========================================

test('guest cannot access admin pages editor', function () {
    $this->get(route('admin.pages.index'))
        ->assertRedirect(route('login'));
});

test('client cannot access admin pages editor', function () {
    $client = User::factory()->individual()->create();

    $this->actingAs($client)
        ->get(route('admin.pages.index'))
        ->assertForbidden();
});

test('guest cannot access admin pages edit', function () {
    $this->get(route('admin.pages.edit', 'terms'))
        ->assertRedirect(route('login'));
});

test('client cannot access admin pages edit', function () {
    $client = User::factory()->individual()->create();

    $this->actingAs($client)
        ->get(route('admin.pages.edit', 'terms'))
        ->assertForbidden();
});

// ===========================================
// Page Model Tests
// ===========================================

test('page has localized title accessor', function () {
    $page = Page::where('slug', 'terms')->first();

    app()->setLocale('ar');
    expect($page->getTitle())->toBe('شروط الخدمة');

    app()->setLocale('en');
    expect($page->getTitle())->toBe('Terms of Service');
});

test('page has localized content accessor', function () {
    Page::where('slug', 'terms')->update([
        'content_ar' => 'محتوى عربي',
        'content_en' => 'English content',
    ]);

    $page = Page::where('slug', 'terms')->first();

    app()->setLocale('ar');
    expect($page->getContent())->toBe('محتوى عربي');

    app()->setLocale('en');
    expect($page->getContent())->toBe('English content');
});

test('page content falls back to arabic when english is empty', function () {
    Page::where('slug', 'terms')->update([
        'content_ar' => 'محتوى عربي',
        'content_en' => null,
    ]);

    $page = Page::where('slug', 'terms')->first();

    app()->setLocale('en');
    // Falls back to Arabic content when English is null
    expect($page->getContent())->toBe('محتوى عربي');
});
