<?php

namespace Tests\Feature\Tenant;

use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;

class SettingsApiTest extends TenantTestCase
{
    use RefreshDatabase;

    protected Tenant $tenant;

    protected User $tenantUser;

    protected string $token;

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

    #[Test]
    public function unauthenticated_users_cannot_access_settings()
    {
        $response = $this->getJson('/api/v1/tenant/settings');

        $response->assertStatus(401);
    }

    #[Test]
    public function authenticated_user_can_get_settings()
    {
        $response = $this->authenticatedRequest('GET', '/api/v1/tenant/settings');

        $response->assertStatus(200)
            ->assertJson(['message' => 'Settings erfolgreich abgerufen.'])
            ->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F')
            ->assertJsonPath('data.settings.features.photo_likes_enabled', true);
    }

    #[Test]
    public function user_can_update_settings()
    {
        $settingsData = [
            'settings' => [
                'branding' => [
                    'logo_url' => 'https://example.com/logo.png',
                    'primary_color' => '#FF6B6B',
                    'secondary_color' => '#4ECDC4',
                ],
                'features' => [
                    'photo_likes_enabled' => false,
                    'event_checklist' => true,
                    'custom_domain' => true,
                ],
                'custom_domain' => 'custom.example.com',
            ],
        ];

        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings', $settingsData);

        $response->assertStatus(200)
            ->assertJson(['message' => 'Settings erfolgreich aktualisiert.'])
            ->assertJsonPath('data.settings.branding.primary_color', '#FF6B6B')
            ->assertJsonPath('data.settings.features.photo_likes_enabled', false)
            ->assertJsonPath('data.settings.custom_domain', 'custom.example.com');

        $this->assertDatabaseHas('tenants', [
            'id' => $this->tenant->id,
            'settings' => json_encode($settingsData['settings']),
        ]);
    }

    #[Test]
    public function settings_update_requires_valid_data()
    {
        $invalidData = [
            'settings' => [
                'branding' => [
                    'primary_color' => 'invalid-color',
                ],
            ],
        ];

        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings', $invalidData);

        $response->assertStatus(422)
            ->assertJsonValidationErrors([
                'settings.branding.primary_color',
            ]);
    }

    #[Test]
    public function user_can_reset_settings_to_defaults()
    {
        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/reset');

        $response->assertStatus(200)
            ->assertJson(['message' => 'Settings auf Standardwerte zurueckgesetzt.'])
            ->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F')
            ->assertJsonPath('data.settings.features.photo_likes_enabled', true);

        $this->assertDatabaseHas('tenants', [
            'id' => $this->tenant->id,
            'settings' => json_encode([
                'branding' => [
                    'logo_url' => null,
                    'primary_color' => '#FF5A5F',
                    'secondary_color' => '#FFF8F5',
                    'font_family' => 'Inter, sans-serif',
                ],
                'features' => [
                    'photo_likes_enabled' => true,
                    'event_checklist' => true,
                    'custom_domain' => false,
                    'advanced_analytics' => false,
                ],
                'custom_domain' => null,
                'contact_email' => $this->tenant->contact_email,
                'event_default_type' => 'general',
            ]),
        ]);
    }

    #[Test]
    public function user_can_validate_domain_availability()
    {
        // Valid domain
        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
            'domain' => 'custom.example.com',
        ]);

        $response->assertStatus(200)
            ->assertJson(['available' => true])
            ->assertJson(['message' => 'Domain ist verfuegbar.']);

        // Invalid domain format
        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
            'domain' => 'invalid@domain',
        ]);

        $response->assertStatus(200)
            ->assertJson(['available' => false])
            ->assertJson(['message' => 'Ungueltiges Domain-Format.']);

        // Taken domain (create another tenant with same domain)
        $otherTenant = Tenant::factory()->create(['custom_domain' => 'taken.example.com']);

        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain', [
            'domain' => 'taken.example.com',
        ]);

        $response->assertStatus(200)
            ->assertJson(['available' => false])
            ->assertJson(['message' => 'Domain ist bereits vergeben.']);
    }

    #[Test]
    public function domain_validation_requires_domain_parameter()
    {
        $response = $this->authenticatedRequest('POST', '/api/v1/tenant/settings/validate-domain');

        $response->assertStatus(400)
            ->assertJsonPath('error.code', 'domain_missing')
            ->assertJsonPath('error.message', 'Bitte gib eine Domain an.');
    }

    #[Test]
    public function settings_are_tenant_isolated()
    {
        $otherTenant = Tenant::factory()->create([
            'settings' => json_encode(['branding' => ['primary_color' => '#FF0000']]),
        ]);
        $otherUser = User::factory()->create([
            'tenant_id' => $otherTenant->id,
            'role' => 'admin',
        ]);
        $otherToken = 'mock-jwt-token-'.$otherTenant->id.'-'.time();

        // This tenant's user should not see other tenant's settings
        $response = $this->authenticatedRequest('GET', '/api/v1/tenant/settings');

        $response->assertStatus(200)
            ->assertJsonPath('data.settings.branding.primary_color', '#FF5A5F') // Default for this tenant
            ->assertJsonMissing(['#FF0000']); // Other tenant's color
    }
}
