<?php

namespace Tests\Feature\Popup;

use App\Models\Members\User;
use App\Models\Members\UserTenant;
use App\Models\Popups\Popup;
use App\Models\Tenants\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;

class PopupApiTest extends TestCase
{
    use DatabaseTransactions;

    private Tenant $tenant;

    private User $user;

    private string $apiKey;

    private string $token;

    protected function setUp(): void
    {
        parent::setUp();

        // 테스트용 API Key 생성
        $this->apiKey = 'test-api-key-'.uniqid();
        \DB::table('api_keys')->insert([
            'key' => $this->apiKey,
            'description' => 'Test API Key',
            'is_active' => true,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        // Tenant 생성 또는 기존 사용
        $this->tenant = Tenant::first() ?? Tenant::withoutEvents(function () {
            return Tenant::create([
                'company_name' => 'Test Company',
                'code' => 'TEST'.uniqid(),
                'email' => 'test@example.com',
                'phone' => '010-1234-5678',
            ]);
        });

        // User 생성
        $testUserId = 'testuser'.uniqid();
        $this->user = User::create([
            'user_id' => $testUserId,
            'name' => 'Test User',
            'email' => $testUserId.'@example.com',
            'password' => bcrypt('password123'),
        ]);

        // UserTenant 관계 생성
        UserTenant::create([
            'user_id' => $this->user->id,
            'tenant_id' => $this->tenant->id,
            'is_active' => true,
            'is_default' => true,
        ]);

        // 로그인 및 토큰 획득
        $this->loginAndGetToken();
    }

    protected function loginAndGetToken(): void
    {
        $response = $this->withHeaders([
            'X-API-KEY' => $this->apiKey,
            'Accept' => 'application/json',
        ])->postJson('/api/v1/login', [
            'user_id' => $this->user->user_id,
            'user_pwd' => 'password123',
        ]);

        $response->assertStatus(200);
        $this->token = $response->json('access_token');
    }

    protected function authenticatedRequest(string $method, string $uri, array $data = [])
    {
        return $this->withHeaders([
            'X-API-KEY' => $this->apiKey,
            'Authorization' => 'Bearer '.$this->token,
            'Accept' => 'application/json',
        ])->{$method.'Json'}($uri, $data);
    }

    // ==================== Popup CRUD Tests ====================

    public function test_can_list_popups(): void
    {
        Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Test Popup 1',
            'content' => 'Test content 1',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('get', '/api/v1/popups');

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'message',
                'data',
            ]);
    }

    public function test_can_create_popup(): void
    {
        $response = $this->authenticatedRequest('post', '/api/v1/popups', [
            'title' => 'New Popup',
            'content' => '<h1>Welcome!</h1><p>This is a new popup.</p>',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->format('Y-m-d H:i:s'),
            'ended_at' => now()->addMonth()->format('Y-m-d H:i:s'),
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'id',
                    'title',
                    'content',
                    'target_type',
                    'status',
                ],
            ]);

        $this->assertDatabaseHas('popups', [
            'title' => 'New Popup',
            'target_type' => 'all',
            'tenant_id' => $this->tenant->id,
        ]);
    }

    public function test_can_show_popup(): void
    {
        $popup = Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Show Test Popup',
            'content' => 'Show test content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('get', "/api/v1/popups/{$popup->id}");

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'id',
                    'title',
                    'content',
                ],
            ])
            ->assertJson([
                'data' => [
                    'title' => 'Show Test Popup',
                ],
            ]);
    }

    public function test_can_update_popup(): void
    {
        $popup = Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Original Popup',
            'content' => 'Original content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('put', "/api/v1/popups/{$popup->id}", [
            'title' => 'Updated Popup',
            'content' => 'Updated content',
            'status' => 'inactive',
        ]);

        $response->assertStatus(200);

        $this->assertDatabaseHas('popups', [
            'id' => $popup->id,
            'title' => 'Updated Popup',
            'status' => 'inactive',
        ]);
    }

    public function test_can_delete_popup(): void
    {
        $popup = Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Delete Test Popup',
            'content' => 'Delete test content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('delete', "/api/v1/popups/{$popup->id}");

        $response->assertStatus(200);

        $this->assertSoftDeleted('popups', [
            'id' => $popup->id,
        ]);
    }

    // ==================== Active Popups Tests ====================

    public function test_can_get_active_popups(): void
    {
        // 활성 팝업 (현재 기간 내)
        Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Active Popup',
            'content' => 'Active content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        // 비활성 팝업
        Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Inactive Popup',
            'content' => 'Inactive content',
            'target_type' => 'all',
            'status' => 'inactive',
            'started_at' => now()->subDay(),
            'ended_at' => now()->addWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        // 기간 만료된 팝업
        Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Expired Popup',
            'content' => 'Expired content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->subMonth(),
            'ended_at' => now()->subWeek(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('get', '/api/v1/popups/active');

        $response->assertStatus(200);

        $data = $response->json('data');
        $this->assertIsArray($data);

        // 활성 팝업만 반환되어야 함
        $titles = collect($data)->pluck('title')->toArray();
        $this->assertContains('Active Popup', $titles);
        $this->assertNotContains('Inactive Popup', $titles);
        $this->assertNotContains('Expired Popup', $titles);
    }

    public function test_active_popups_respects_date_range(): void
    {
        // 아직 시작 안 된 팝업
        Popup::create([
            'tenant_id' => $this->tenant->id,
            'title' => 'Future Popup',
            'content' => 'Future content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->addWeek(),
            'ended_at' => now()->addMonth(),
            'created_by' => $this->user->id,
            'updated_by' => $this->user->id,
        ]);

        $response = $this->authenticatedRequest('get', '/api/v1/popups/active');

        $response->assertStatus(200);

        $data = $response->json('data');
        $titles = collect($data)->pluck('title')->toArray();
        $this->assertNotContains('Future Popup', $titles);
    }

    // ==================== Target Type Tests ====================

    public function test_can_create_popup_with_department_target(): void
    {
        // TODO: FormRequest 유효성 검사 규칙에 따라 target_id 검증 필요
        // 현재 API는 target_type=department일 때 추가 검증이 있을 수 있음
        $this->markTestSkipped('Department target validation rules need to be verified');

        $response = $this->authenticatedRequest('post', '/api/v1/popups', [
            'title' => 'Department Popup',
            'content' => 'For specific department',
            'target_type' => 'department',
            'target_id' => 1,
            'status' => 'active',
            'started_at' => now()->format('Y-m-d H:i:s'),
            'ended_at' => now()->addMonth()->format('Y-m-d H:i:s'),
        ]);

        $response->assertStatus(201);

        $this->assertDatabaseHas('popups', [
            'title' => 'Department Popup',
            'target_type' => 'department',
            'target_id' => 1,
        ]);
    }

    // ==================== Validation Tests ====================

    public function test_cannot_create_popup_without_required_fields(): void
    {
        $response = $this->authenticatedRequest('post', '/api/v1/popups', [
            // title 누락
            'content' => 'Some content',
        ]);

        $response->assertStatus(422);
    }

    public function test_cannot_create_popup_with_invalid_date_range(): void
    {
        $response = $this->authenticatedRequest('post', '/api/v1/popups', [
            'title' => 'Invalid Date Popup',
            'content' => 'Content',
            'target_type' => 'all',
            'status' => 'active',
            'started_at' => now()->addMonth()->format('Y-m-d H:i:s'),
            'ended_at' => now()->format('Y-m-d H:i:s'), // 시작일보다 이전
        ]);

        // 유효성 검사 실패 예상
        $response->assertStatus(422);
    }

    // ==================== Authentication Tests ====================

    public function test_cannot_access_popups_without_authentication(): void
    {
        $response = $this->withHeaders([
            'X-API-KEY' => $this->apiKey,
            'Accept' => 'application/json',
        ])->getJson('/api/v1/popups');

        $response->assertStatus(401);
    }
}
