<?php

namespace Tests\Feature;

use App\Models\Sponsor;
use App\Models\User;
use App\Models\EmployerProfile;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class SponsorAuthApiTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Test a pure Sponsor can register with simple info and a license file upload.
     */
    public function test_sponsor_can_register_with_license()
    {
        $licenseFile = UploadedFile::fake()->create('license.pdf', 500, 'application/pdf');

        $response = $this->postJson('/api/sponsors/register', [
            'full_name'         => 'Test Sponsor Organization',
            'mobile'            => '+971509990001',
            'password'          => 'securepassword',
            'license_file'      => $licenseFile,
            'organization_name' => 'Charity Co',
            'nationality'       => 'Emirati',
            'city'              => 'Abu Dhabi',
        ]);

        $response->assertStatus(201)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'sponsor' => [
                        'id',
                        'full_name',
                        'mobile',
                        'organization_name',
                        'nationality',
                        'city',
                        'license_file',
                    ],
                    'token',
                ]
            ]);

        $this->assertDatabaseHas('sponsors', [
            'mobile' => '+971509990001',
            'full_name' => 'Test Sponsor Organization',
        ]);
    }

    /**
     * Test both Sponsor and Employer can log in using the unified login endpoint.
     */
    public function test_unified_login_returns_correct_role_and_data()
    {
        // 1. Create a pure Sponsor (no User record)
        $sponsorUser = Sponsor::create([
            'full_name'         => 'Sponsor User',
            'email'             => 'sponsor@example.com',
            'mobile'            => '+971509991111',
            'password'          => Hash::make('password123'),
            'license_file'      => 'uploads/licenses/fake.pdf',
            'status'            => 'active',
        ]);

        // 2. Create an Employer (has both User and Sponsor records, legacy setup)
        $employerUser = User::create([
            'name'      => 'Employer User',
            'email'     => 'employer@example.com',
            'password'  => Hash::make('password123'),
            'role'      => 'employer',
            'api_token' => 'old_token',
        ]);

        EmployerProfile::create([
            'user_id'             => $employerUser->id,
            'company_name'        => 'Employer Corp',
            'phone'               => '+971509992222',
            'country'             => 'United Arab Emirates',
            'verification_status' => 'approved',
        ]);

        Sponsor::create([
            'full_name' => 'Employer User',
            'email'     => 'employer@example.com',
            'mobile'    => '+971509992222',
            'password'  => $employerUser->password,
            'status'    => 'active',
        ]);

        // --- Test Sponsor Login via /api/employers/login ---
        $responseSponsor = $this->postJson('/api/employers/login', [
            'mobile'   => '+971509991111',
            'password' => 'password123',
        ]);

        $responseSponsor->assertStatus(200)
            ->assertJson([
                'success' => true,
                'role'    => 'sponsor',
            ])
            ->assertJsonStructure([
                'data' => [
                    'sponsor',
                    'token',
                ]
            ]);

        // --- Test Employer Login via /api/employers/login ---
        $responseEmployer = $this->postJson('/api/employers/login', [
            'mobile'   => '+971509992222',
            'password' => 'password123',
        ]);

        $responseEmployer->assertStatus(200)
            ->assertJson([
                'success' => true,
                'role'    => 'employer',
            ])
            ->assertJsonStructure([
                'data' => [
                    'employer' => [
                        'id',
                        'name',
                        'email',
                        'employer_profile',
                    ],
                    'token',
                ]
            ]);
    }

    /**
     * Test that pure sponsors can only access their limited routes.
     */
    public function test_sponsor_restricted_access()
    {
        $sponsor = Sponsor::create([
            'full_name' => 'Pure Sponsor',
            'email'     => 'pure_sponsor@example.com',
            'mobile'    => '+971509993333',
            'password'  => Hash::make('password123'),
            'api_token' => 'sponsor_token_abc',
            'status'    => 'active',
        ]);

        // Access dashboard successfully
        $responseDash = $this->withHeaders([
            'Authorization' => 'Bearer sponsor_token_abc',
        ])->getJson('/api/sponsors/dashboard');

        $responseDash->assertStatus(200);

        // Try to access employer protected route (should get blocked as they don't have employer token/role)
        $responseEmployerRoute = $this->withHeaders([
            'Authorization' => 'Bearer sponsor_token_abc',
        ])->getJson('/api/employers/profile');

        $responseEmployerRoute->assertStatus(401);
    }

    /**
     * Test that a sponsor can post a charity event.
     */
    public function test_sponsor_can_post_charity_event()
    {
        $sponsor = Sponsor::create([
            'full_name'         => 'Test Sponsor',
            'organization_name' => 'Save the Children',
            'email'             => 'tsponsor@example.com',
            'mobile'            => '+971509994444',
            'password'          => Hash::make('password123'),
            'api_token'         => 'sponsor_token_xyz',
            'status'            => 'active',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer sponsor_token_xyz',
        ])->postJson('/api/sponsors/charity-events', [
            'title' => 'Community Ramadan Iftar',
            'body'  => 'Join us for a free community Iftar gathering at the center.',
            'type'  => 'charity',
        ]);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
                'message' => 'Charity event posted successfully.',
            ])
            ->assertJsonStructure([
                'data' => [
                    'id',
                    'title',
                    'body',
                    'type',
                    'posted_by',
                    'organization',
                    'created_at',
                ]
            ]);

        $this->assertDatabaseHas('announcements', [
            'title'      => 'Community Ramadan Iftar',
            'sponsor_id' => $sponsor->id,
            'status'     => 'pending',
        ]);
    }

    /**
     * Test that a sponsor can list charity events showing both employer and sponsor events.
     */
    public function test_sponsor_can_list_charity_events()
    {
        $sponsor = Sponsor::create([
            'full_name'         => 'Test Sponsor',
            'organization_name' => 'Save the Children',
            'email'             => 'tsponsor@example.com',
            'mobile'            => '+971509994444',
            'password'          => Hash::make('password123'),
            'api_token'         => 'sponsor_token_xyz',
            'status'            => 'active',
        ]);

        // Post a sponsor announcement
        \App\Models\Announcement::create([
            'title'      => 'Sponsor Event',
            'body'       => 'Body of sponsor event',
            'type'       => 'charity',
            'sponsor_id' => $sponsor->id,
            'status'     => 'approved',
        ]);

        // Post an employer announcement
        $employer = User::create([
            'name'     => 'Employer User',
            'email'    => 'employer@example.com',
            'password' => Hash::make('password123'),
            'role'     => 'employer',
        ]);
        EmployerProfile::create([
            'user_id'      => $employer->id,
            'company_name' => 'Employer Co',
            'phone'        => '+971509995555',
            'country'      => 'United Arab Emirates',
        ]);
        \App\Models\Announcement::create([
            'title'       => 'Employer Event',
            'body'        => 'Body of employer event',
            'type'        => 'charity',
            'employer_id' => $employer->id,
            'status'      => 'approved',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer sponsor_token_xyz',
        ])->getJson('/api/sponsors/charity-events');

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
            ]);

        $events = $response->json('data.events');
        $this->assertCount(2, $events);

        // Verify sponsor event details
        $this->assertEquals('Sponsor Event', $events[0]['title']);
        $this->assertEquals('Test Sponsor', $events[0]['posted_by']);
        $this->assertEquals('Save the Children', $events[0]['organization']);

        // Verify employer event details
        $this->assertEquals('Employer Event', $events[1]['title']);
        $this->assertEquals('Employer User', $events[1]['posted_by']);
        $this->assertEquals('Employer Co', $events[1]['organization']);
    }

    /**
     * Test that sponsor dashboard returns correct employer and worker counts.
     */
    public function test_sponsor_dashboard_returns_stats()
    {
        $sponsor = Sponsor::create([
            'full_name'         => 'Test Sponsor',
            'organization_name' => 'Save the Children',
            'email'             => 'tsponsor@example.com',
            'mobile'            => '+971509994444',
            'password'          => Hash::make('password123'),
            'api_token'         => 'sponsor_token_xyz',
            'status'            => 'active',
        ]);

        // Create some employers (Users with role = employer)
        User::create([
            'name'                => 'Emp 1',
            'email'               => 'emp1@example.com',
            'password'            => Hash::make('password123'),
            'role'                => 'employer',
            'subscription_status' => 'active',
        ]);
        User::create([
            'name'                => 'Emp 2',
            'email'               => 'emp2@example.com',
            'password'            => Hash::make('password123'),
            'role'                => 'employer',
            'subscription_status' => 'none',
        ]);

        $category = \App\Models\WorkerCategory::create([
            'name' => 'Housemaid',
        ]);

        // Create some workers
        \App\Models\Worker::create([
            'name'         => 'Worker 1',
            'email'        => 'w1@example.com',
            'phone'        => '+971509998881',
            'password'     => Hash::make('password123'),
            'status'       => 'active',
            'language'     => 'en',
            'nationality'  => 'Indian',
            'city'         => 'Dubai',
            'age'          => 25,
            'salary'       => 1500,
            'experience'   => 'None',
            'religion'     => 'Christian',
            'bio'          => 'Test',
            'category_id'  => $category->id,
            'availability' => 'Immediate',
        ]);
        \App\Models\Worker::create([
            'name'         => 'Worker 2',
            'email'        => 'w2@example.com',
            'phone'        => '+971509998882',
            'password'     => Hash::make('password123'),
            'status'       => 'hidden',
            'language'     => 'en',
            'nationality'  => 'Indian',
            'city'         => 'Dubai',
            'age'          => 25,
            'salary'       => 1500,
            'experience'   => 'None',
            'religion'     => 'Christian',
            'bio'          => 'Test',
            'category_id'  => $category->id,
            'availability' => 'Immediate',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer sponsor_token_xyz',
        ])->getJson('/api/sponsors/dashboard');

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'data' => [
                    'employer_stats' => [
                        'total' => 2,
                        'active' => 1,
                    ],
                    'worker_stats' => [
                        'total' => 2,
                        'active' => 1,
                    ],
                ],
            ]);
    }
}
