<?php

namespace Tests\Feature\Mexco;

use App\Models\MeetupEvent;
use App\Models\MeetupParticipant;
use App\Models\MeetupRole;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class OrganiserCommitteeRegistrationTest extends TestCase
{
    use RefreshDatabase;

    protected function actingAsOrganiser(string $eventId): static
    {
        return $this->withSession([
            'meetup_admin_authenticated' => true,
            'meetup_admin_event' => $eventId,
        ]);
    }

    protected function seedEvent(): MeetupEvent
    {
        return MeetupEvent::query()->create([
            'id' => 'org-event-1',
            'name' => 'Organiser Event',
            'event_name' => 'Organiser Event',
            'short_name' => 'Org Event',
            'organiser_username' => 'organiser@test.mexco',
            'organiser_password' => '1234',
            'starts_at' => now()->subDay(),
            'ends_at' => now()->addDays(7),
        ]);
    }

    public function test_organiser_can_register_committee_account(): void
    {
        $event = $this->seedEvent();

        $this->actingAsOrganiser($event->id)
            ->post(route('mexco.admin.committee.store'), [
                'name' => 'Check-in Staff',
                'email' => 'staff@test.mexco',
                'ic' => '910303145678',
                'org' => 'Event Ops',
                'phone' => '0123456789',
                'role' => 'COMMITTEE',
            ])
            ->assertRedirect(route('mexco.admin.committee'));

        $this->assertDatabaseHas('meetup_participants', [
            'event_id' => $event->id,
            'email' => 'staff@test.mexco',
            'role' => 'VISITOR',
            'is_committee' => 1,
        ]);

        $this->assertDatabaseHas('meetup_roles', [
            'event_id' => $event->id,
            'name' => 'COMMITTEE',
        ]);

        $this->postJson('/mexco/api/auth/attend', [
            'email' => 'staff@test.mexco',
            'ic' => '910303145678',
        ])->assertOk()
            ->assertJsonPath('matches.0.eventId', $event->id);
    }

    public function test_existing_participant_can_be_promoted_to_committee(): void
    {
        $event = $this->seedEvent();

        MeetupParticipant::query()->create([
            'event_id' => $event->id,
            'slug' => 'visitor_test_mexco',
            'email' => 'visitor@test.mexco',
            'name' => 'Existing Visitor',
            'ic' => '900101123456',
            'org' => 'UMPSA',
            'role' => 'VISITOR',
            'booth_stamps' => [],
            'session_attendance' => [],
        ]);

        $this->actingAsOrganiser($event->id)
            ->post(route('mexco.admin.committee.lookup'), [
                'email' => 'visitor@test.mexco',
            ])
            ->assertRedirect(route('mexco.admin.committee.create'));

        $this->actingAsOrganiser($event->id)
            ->post(route('mexco.admin.committee.store'), [
                'email' => 'visitor@test.mexco',
            ])
            ->assertRedirect(route('mexco.admin.committee'))
            ->assertSessionHas('success');

        $this->assertDatabaseHas('meetup_participants', [
            'event_id' => $event->id,
            'email' => 'visitor@test.mexco',
            'role' => 'VISITOR',
            'is_committee' => 1,
            'name' => 'Existing Visitor',
        ]);
    }

    public function test_committee_registration_requires_ic(): void
    {
        $event = $this->seedEvent();

        $this->actingAsOrganiser($event->id)
            ->from(route('mexco.admin.committee.create'))
            ->post(route('mexco.admin.committee.store'), [
                'name' => 'No IC Staff',
                'email' => 'noic@test.mexco',
                'ic' => '',
            ])
            ->assertRedirect(route('mexco.admin.committee.create'))
            ->assertSessionHasErrors('ic');
    }

    public function test_organiser_committee_index_lists_only_attend_roles(): void
    {
        $event = $this->seedEvent();
        MeetupRole::query()->create([
            'event_id' => $event->id,
            'name' => 'COMMITTEE',
            'sessions_limit' => null,
            'stamps_required' => 0,
        ]);

        MeetupParticipant::query()->create([
            'event_id' => $event->id,
            'slug' => 'visitor_test',
            'email' => 'visitor@test.mexco',
            'name' => 'Visitor',
            'ic' => '900101123456',
            'role' => 'VISITOR',
            'booth_stamps' => [],
            'session_attendance' => [],
        ]);

        MeetupParticipant::query()->create([
            'event_id' => $event->id,
            'slug' => 'staff_test',
            'email' => 'staff@test.mexco',
            'name' => 'Staff',
            'ic' => '910303145678',
            'role' => 'COMMITTEE',
            'booth_stamps' => [],
            'session_attendance' => [],
        ]);

        MeetupParticipant::query()->where('email', 'staff@test.mexco')->update(['is_committee' => true]);

        $this->actingAsOrganiser($event->id)
            ->get(route('mexco.admin.committee'))
            ->assertOk()
            ->assertSee('staff@test.mexco')
            ->assertDontSee('visitor@test.mexco');
    }
}
