<?php

namespace Tests\Feature;

use App\Enums\LicenseStatus;
use App\Filament\AssociationAdmin\Resources\AssociationStationLicenseResource;
use App\Filament\AssociationAdmin\Resources\AssociationStationLicenseResource\Pages\ListAssociationStationLicenses;
use App\Filament\AssociationAdmin\Resources\AssociationWellLicenseResource;
use App\Filament\AssociationAdmin\Resources\AssociationWellLicenseResource\Pages\CreateAssociationWellLicense;
use App\Filament\AssociationAdmin\Resources\AssociationWellLicenseResource\Pages\ListAssociationWellLicenses;
use App\Models\Association;
use App\Models\City;
use App\Models\State;
use App\Models\StationLicense;
use App\Models\User;
use App\Models\WellLicense;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\TestCase;

class AssociationLicensingTest extends TestCase
{
    use RefreshDatabase;

    protected User $user;

    protected Association $association;

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

        // Set up the AssociationAdmin panel
        Filament::setCurrentPanel(Filament::getPanel('associationAdmin'));

        // Create an association
        $this->association = Association::factory()->create();

        // Create a user with association
        $this->user = User::factory()->create([
            'association_id' => $this->association->id,
        ]);

        // Authenticate the user
        $this->actingAs($this->user);
    }

    public function test_association_user_can_view_well_licenses_list(): void
    {
        // Create a well license for the user's association
        $wellLicense = WellLicense::factory()->create([
            'association_id' => $this->association->id,
            'created_by' => $this->user->id,
        ]);

        // Create a well license for another association (should not be visible)
        $otherAssociation = Association::factory()->create();
        WellLicense::factory()->create([
            'association_id' => $otherAssociation->id,
        ]);

        Livewire::test(ListAssociationWellLicenses::class)
            ->assertCanSeeTableRecords([$wellLicense])
            ->assertCountTableRecords(1);
    }

    public function test_association_user_can_create_well_license(): void
    {
        $state = State::factory()->create();
        $city = City::factory()->create(['state_id' => $state->id]);

        Livewire::test(CreateAssociationWellLicense::class)
            ->fillForm([
                'well_name' => 'Test Well',
                'state_id' => $state->id,
                'city_id' => $city->id,
                'lat' => 24.7136,
                'lng' => 46.6753,
                'well_depth' => 100.5,
                'well_diameter' => 12.5,
                'pump_size' => 50,
                'withdrawal_amount' => 1000,
            ])
            ->call('create')
            ->assertHasNoFormErrors();

        $this->assertDatabaseHas('well_licenses', [
            'well_name' => 'Test Well',
            'association_id' => $this->association->id,
            'created_by' => $this->user->id,
            'status' => LicenseStatus::CREATED,
        ]);
    }

    public function test_association_user_can_view_station_licenses_list(): void
    {
        // Create a station license for the user's association
        $stationLicense = StationLicense::factory()->create([
            'association_id' => $this->association->id,
            'created_by' => $this->user->id,
        ]);

        // Create a station license for another association (should not be visible)
        $otherAssociation = Association::factory()->create();
        StationLicense::factory()->create([
            'association_id' => $otherAssociation->id,
        ]);

        Livewire::test(ListAssociationStationLicenses::class)
            ->assertCanSeeTableRecords([$stationLicense])
            ->assertCountTableRecords(1);
    }

    public function test_association_user_cannot_see_other_association_licenses(): void
    {
        // Create licenses for another association
        $otherAssociation = Association::factory()->create();
        $otherWellLicense = WellLicense::factory()->create([
            'association_id' => $otherAssociation->id,
        ]);
        $otherStationLicense = StationLicense::factory()->create([
            'association_id' => $otherAssociation->id,
        ]);

        // Test well licenses
        Livewire::test(ListAssociationWellLicenses::class)
            ->assertCanNotSeeTableRecords([$otherWellLicense])
            ->assertCountTableRecords(0);

        // Test station licenses
        Livewire::test(ListAssociationStationLicenses::class)
            ->assertCanNotSeeTableRecords([$otherStationLicense])
            ->assertCountTableRecords(0);
    }

    public function test_resources_are_properly_registered(): void
    {
        $this->assertTrue(class_exists(AssociationWellLicenseResource::class));
        $this->assertTrue(class_exists(AssociationStationLicenseResource::class));

        $this->assertStringContainsString(
            'well-licenses',
            AssociationWellLicenseResource::getUrl('index')
        );

        $this->assertStringContainsString(
            'station-licenses',
            AssociationStationLicenseResource::getUrl('index')
        );
    }
}
