<?php

namespace Tests\Tenant;

use App\Http\Resources\MenuList;
use App\Http\Resources\MenuView;
use App\Http\Resources\SearchResponse;
use Mtc\ContentManager\Contracts\MediaUse;
use Mtc\ContentManager\Http\Resources\MediaEntryResource;
use Mtc\ContentManager\Http\Resources\MediaFileResource;
use Mtc\ContentManager\Http\Resources\MediaListResource;
use Mtc\ContentManager\Models\ContentElement;
use Mtc\ContentManager\Models\Media;
use Mtc\ContentManager\Models\Menu;
use Mtc\ContentManager\Models\MenuEntry;
use Mtc\MercuryDataModels\Form;
use Mtc\MercuryDataModels\GlobalContent;
use Mtc\MercuryDataModels\Page;
use Tests\TenantTestCase;
use Tests\UserForTenant;

class ResourceTest extends TenantTestCase
{
    use UserForTenant;


    public function testMediaEntry()
    {
        $media = Media::factory()->create([
            'src' => 'foo.png',
            'title' => 'foo',
            'type' => 'image',
        ]);

        $mediaUse = MediaUse::factory()->create([
            'media_id' => $media->id,
        ]);

        $resource = new MediaEntryResource($mediaUse)->toArray(request());

        $this->assertArrayHasKey('media', $resource);
        $this->assertEquals($mediaUse->id, $resource['id']);
        $this->assertEquals($media->id, $resource['media']['id']);
        $this->assertStringContainsString($media->src, $resource['media']['src']);
        $this->assertEquals($media->title, $resource['media']['title']);
        $this->assertEquals($media->type, $resource['media']['type']);
    }

    public function testMediaFile()
    {
        $media = Media::factory()->create([
            'src' => 'foo.png',
            'title' => 'foo',
            'type' => 'image',
        ]);

        $resource = new MediaFileResource($media)->toArray(request());

        $this->assertArrayHasKey('extension', $resource);
        $this->assertEquals($media->id, $resource['id']);
        $this->assertStringContainsString($media->src, $resource['src']);
        $this->assertEquals('png', $resource['extension']);
        $this->assertEquals($media->title, $resource['title']);
        $this->assertEquals($media->type, $resource['type']);
    }

    public function testMediaList()
    {
        $list = Media::factory(10)->create();

        $resource = new MediaListResource($list)->toArray(request());
        $this->assertCount(10, $resource);

        $list = Media::query()->paginate(8);
        $resource = new MediaListResource($list)->toArray(request());

        $this->assertArrayHasKey('data', $resource);
        $this->assertCount(8, $resource['data']);
        $this->assertArrayHasKey('total', $resource);
    }

    public function testMenuList()
    {
        $list = Menu::factory(10)->create();
        $resource = new MenuList($list)->toArray(request());
        $this->assertCount(10, $resource);

        $list = Menu::query()->paginate(8);
        $resource = new MenuList($list)->toArray(request());

        $this->assertArrayHasKey('data', $resource);
        $this->assertCount(8, $resource['data']);
        $this->assertArrayHasKey('total', $resource);
    }

    public function testMenuView()
    {
        $menu = Menu::factory()->create([
            'title' => 'foo'
        ]);
        $entries = MenuEntry::factory(10)
            ->create([
                'menu_id' => $menu->id,
                'parent_id' => null,
                'is_enabled' => true,
            ]);
        $resource = new MenuView($menu)->toArray(request());

        $this->assertEquals('foo', $resource['title']);
        $this->assertArrayHasKey('root_entries', $resource);
        $this->assertCount(10, $resource['root_entries']);
    }

    public function testElementList()
    {
        ContentElement::factory(4)->create([
            'is_enabled' => true,
            'drag_and_drop' => true,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('content.elements.index'));
        $response->assertStatus(200);
        $this->assertArrayHasKey('id', $response->json('data.0'));
        $this->assertArrayHasKey('title', $response->json('data.0'));
        $this->assertArrayHasKey('description', $response->json('data.0'));
        $this->assertArrayHasKey('metaItems', $response->json('data.0'));
    }

    public function testElementView()
    {
        $element = ContentElement::factory()->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('content.elements.show', $element));
        $response->assertStatus(200);
        $this->assertArrayHasKey('id', $response->json('data'));
        $this->assertArrayHasKey('title', $response->json('data'));
        $this->assertArrayHasKey('slug', $response->json('data'));
        $this->assertArrayHasKey('data', $response->json());
        $this->assertArrayHasKey('primitives', $response->json());
        $this->assertArrayHasKey('elements', $response->json());
        $this->assertArrayHasKey('categories', $response->json());
    }

    public function testFormView()
    {
        $form = Form::factory()->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('forms.show', $form));
        $response->assertStatus(200);
        $this->assertArrayHasKey('id', $response->json('form'));
        $this->assertArrayHasKey('name', $response->json('form'));
        $this->assertArrayHasKey('available_actions', $response->json('form'));
        $this->assertArrayHasKey('action_data', $response->json('form'));
        $this->assertArrayHasKey('form', $response->json());
        $this->assertArrayHasKey('statuses', $response->json());
        $this->assertArrayHasKey('types', $response->json());
    }

    public function testFormViewWithMissingTemplate()
    {
        $enquiryType = \Mtc\Crm\Models\EnquiryType::factory()->create([
            'template_name' => 'NonExistent Template',
        ]);

        $form = Form::factory()->create([
            'type_id' => $enquiryType->id,
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('forms.show', $form));

        $response->assertStatus(200);
        $this->assertArrayHasKey('preview_content', $response->json('form'));
        $this->assertEquals(
            'Email template not found. Please check the enquiry type configuration.',
            $response->json('form.preview_content')
        );
    }

    public function testGlobalContentView()
    {
        $content = GlobalContent::factory()->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('content.global-elements.show', $content));
        $response->assertStatus(200);
        $this->assertArrayHasKey('id', $response->json('data'));
        $this->assertArrayHasKey('name', $response->json('data'));
        $this->assertArrayHasKey('content', $response->json('data'));
        $this->assertArrayHasKey('ui_component', $response->json('data'));
    }


    public function testSearchResponse()
    {
        $pages = Page::factory(3)->create(['title' => 'foo']);
        $response = new SearchResponse($pages)->toArray(request());

        $this->assertArrayHasKey('data', $response);
        $this->assertArrayHasKey('search_types', $response);
        $this->assertArrayHasKey('name', $response['data'][0]);
        $this->assertArrayHasKey('description', $response['data'][0]);
        $this->assertArrayHasKey('icon', $response['data'][0]);
        $this->assertArrayHasKey('route', $response['data'][0]);
    }
}
