<?php

namespace Tests\Feature\Controllers;

use App\Models\NotificationMap;
use App\Models\NotificationTemplate;
use Tests\DatabaseTestCase;
use Tests\UserForTenant;

class NotificationMapControllerTest extends DatabaseTestCase
{
    use UserForTenant;

    protected function setUp(): void
    {
        parent::setUp();
        $this->withHeader('X-Tenant', tenant('id'));
    }

    public function testStoreCreatesEmptyMap(): void
    {
        $response = $this->actingAs($this->getUser())
            ->postJson('api/settings/notification-maps', ['name' => 'Partner Feed', 'type' => 'vehicle']);

        $response->assertStatus(201);
        $this->assertSame('vehicle', $response->json('type'));
        $this->assertSame('partner-feed', $response->json('slug'));
    }

    public function testStoreRejectsReservedSlug(): void
    {
        $response = $this->actingAs($this->getUser())
            ->postJson('api/settings/notification-maps', ['name' => 'AutoGrab']);

        $response->assertStatus(422);
        $this->assertSame(0, NotificationMap::query()->where('slug', 'autograb')->count());
    }

    public function testStoreFromTemplateCopiesStructure(): void
    {
        $template = NotificationTemplate::query()->create([
            'title' => 'Seed',
            'type' => 'vehicle',
            'is_published' => true,
            'field_map' => [['source' => 'stock_id', 'destination' => 'uuid', 'type' => 'string']],
            'validation' => ['uuid' => ['required', 'string']],
            'config' => ['images' => ['url_key' => 'url']],
        ]);

        $response = $this->actingAs($this->getUser())
            ->postJson('api/settings/notification-maps', [
                'name' => 'From Template',
                'template_id' => $template->id,
            ]);

        $response->assertStatus(201);
        $this->assertSame($template->id, $response->json('template_id'));
        $this->assertSame($template->field_map, $response->json('field_map'));
        $this->assertSame($template->validation, $response->json('validation'));
    }

    public function testStoreWithMissingTemplateIsRejected(): void
    {
        $response = $this->actingAs($this->getUser())
            ->postJson('api/settings/notification-maps', [
                'name' => 'Bad Template',
                'template_id' => 999999,
            ]);

        $response->assertStatus(422);
    }

    public function testUpdatePersistsFieldMapAndActive(): void
    {
        $map = NotificationMap::query()->create(['name' => 'Editable', 'type' => 'vehicle']);

        $response = $this->actingAs($this->getUser())
            ->putJson('api/settings/notification-maps/' . $map->id, [
                'name' => 'Editable',
                'active' => true,
                'field_map' => [['source' => 'reg', 'destination' => 'registration_number', 'type' => 'string']],
                'validation' => ['uuid' => ['required']],
                'config' => [],
            ]);

        $response->assertStatus(200);
        $map->refresh();
        $this->assertTrue($map->active);
        $this->assertCount(1, $map->field_map);
        $this->assertSame('registration_number', $map->field_map[0]['destination']);
    }

    public function testShowReturnsInboundUrlAndDataOptions(): void
    {
        $map = NotificationMap::query()->create(['name' => 'Shown', 'type' => 'vehicle']);

        $response = $this->actingAs($this->getUser())
            ->getJson('api/settings/notification-maps/' . $map->id);

        $response->assertStatus(200);
        $this->assertStringContainsString('/api/notifications/', $response->json('inbound_url'));
        $this->assertNotEmpty($response->json('data_options.available_fields'));
        $this->assertNotEmpty($response->json('data_options.field_types'));
    }

    public function testDestroyRemovesMap(): void
    {
        $map = NotificationMap::query()->create(['name' => 'Removable', 'type' => 'vehicle']);

        $response = $this->actingAs($this->getUser())
            ->deleteJson('api/settings/notification-maps/' . $map->id);

        $response->assertStatus(200);
        $this->assertNull(NotificationMap::query()->find($map->id));
    }
}
