<?php

namespace Tests\Unit;

use App\Models\City;
use App\Models\State;
use App\Services\LocationCoordinatesService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LocationCoordinatesServiceTest extends TestCase
{
    use RefreshDatabase;

    protected LocationCoordinatesService $service;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service = new LocationCoordinatesService;
    }

    public function test_get_state_coordinates_returns_coordinates_when_available(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $coordinates = $this->service->getStateCoordinates($state->id);

        $this->assertEquals([
            'lat' => 24.7136,
            'lng' => 46.6753,
        ], $coordinates);
    }

    public function test_get_state_coordinates_returns_null_when_coordinates_not_available(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => null,
            'lng' => null,
        ]);

        $coordinates = $this->service->getStateCoordinates($state->id);

        $this->assertNull($coordinates);
    }

    public function test_get_city_coordinates_returns_city_coordinates_when_available(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $city = City::factory()->create([
            'name' => ['ar' => 'جدة', 'en' => 'Jeddah'],
            'state_id' => $state->id,
            'lat' => 21.2854,
            'lng' => 39.2376,
        ]);

        $coordinates = $this->service->getCityCoordinates($city->id);

        $this->assertEquals([
            'lat' => 21.2854,
            'lng' => 39.2376,
        ], $coordinates);
    }

    public function test_get_city_coordinates_falls_back_to_state_when_city_coordinates_unavailable(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $city = City::factory()->create([
            'name' => ['ar' => 'مدينة', 'en' => 'City'],
            'state_id' => $state->id,
            'lat' => null,
            'lng' => null,
        ]);

        $coordinates = $this->service->getCityCoordinates($city->id);

        $this->assertEquals([
            'lat' => 24.7136,
            'lng' => 46.6753,
        ], $coordinates);
    }

    public function test_get_best_coordinates_returns_city_coordinates_when_available(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $city = City::factory()->create([
            'name' => ['ar' => 'جدة', 'en' => 'Jeddah'],
            'state_id' => $state->id,
            'lat' => 21.2854,
            'lng' => 39.2376,
        ]);

        $coordinates = $this->service->getBestCoordinates($city->id, $state->id);

        $this->assertEquals([
            'lat' => 21.2854,
            'lng' => 39.2376,
        ], $coordinates);
    }

    public function test_get_best_coordinates_falls_back_to_state_when_no_city(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $coordinates = $this->service->getBestCoordinates(null, $state->id);

        $this->assertEquals([
            'lat' => 24.7136,
            'lng' => 46.6753,
        ], $coordinates);
    }

    public function test_get_best_coordinates_returns_default_when_no_coordinates_available(): void
    {
        $coordinates = $this->service->getBestCoordinates();

        $this->assertEquals([
            'lat' => 24.7136, // Default Riyadh coordinates
            'lng' => 46.6753,
        ], $coordinates);
    }

    public function test_get_center_coordinates_for_cities_calculates_center_point(): void
    {
        $state = State::factory()->create([
            'name' => ['ar' => 'الرياض', 'en' => 'Riyadh'],
            'lat' => 24.7136,
            'lng' => 46.6753,
        ]);

        $city1 = City::factory()->create([
            'name' => ['ar' => 'مدينة1', 'en' => 'City1'],
            'state_id' => $state->id,
            'lat' => 24.0000,
            'lng' => 46.0000,
        ]);

        $city2 = City::factory()->create([
            'name' => ['ar' => 'مدينة2', 'en' => 'City2'],
            'state_id' => $state->id,
            'lat' => 26.0000,
            'lng' => 48.0000,
        ]);

        $coordinates = $this->service->getCenterCoordinatesForCities([$city1->id, $city2->id]);

        $this->assertEquals([
            'lat' => 25.0000, // Average of 24 and 26
            'lng' => 47.0000, // Average of 46 and 48
        ], $coordinates);
    }

    public function test_get_center_coordinates_for_cities_returns_default_when_empty_array(): void
    {
        $coordinates = $this->service->getCenterCoordinatesForCities([]);

        $this->assertEquals([
            'lat' => 24.7136, // Default Riyadh coordinates
            'lng' => 46.6753,
        ], $coordinates);
    }
}
