<?php

namespace Tests\Feature;

use App\ElementRepository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\App;
use Mtc\ContentManager\Contracts\ElementRepositoryContract;
use Mtc\ContentManager\Models\ContentElementField;
use Mtc\MercuryDataModels\ContentElement;
use Tests\TenantTestCase;
use Tests\TestCase;

class ElementRepositoryTest extends TenantTestCase
{
    public function testListOptions()
    {
        ContentElement::factory(10)->create();
        ContentElement::factory(5)->create(['category' => 'foo']);
        $list = $this->repository()->listOptions();
        $this->assertEquals(15, $list->count());
        $list = $this->repository()->listOptions('foo');
        $this->assertEquals(5, $list->count());
    }

    public function testUpdate()
    {
        $element = ContentElement::factory()->create();
        $result = $this->repository()->update($element, [
            'title' => 'foo baz bar',
            'subtitle' => 'lorem ipsum',
            'icon' => 'baz',
            'category' => 'faz',
            'ui_component' => 'foo',
            'is_enabled' => true,
            'drag_and_drop' => true,
            'fields' => [
                [
                    'field_type' => 'image',
                    'name' => 'Image',
                    'slug' => 'image',
                    'data' => [
                        "nestable" => false,
                        "fieldId" => "image",
                        "componentName" => "ImageUpload",
                        "component" => "EditableContentImageUpload",
                        'icon' => 'image',
                        'meta' => [
                            'options' => [
                                'maxCount' => 1,
                            ]
                        ]
                    ],
                ],
                [
                    'field_type' => 'element',
                    'element_id' => 11,
                    'name' => 'Image',
                    'slug' => 'image',
                    'data' => [
                        "nestable" => false,
                        "fieldId" => "image",
                        "componentName" => "ImageUpload",
                        "component" => "EditableContentImageUpload",
                        'icon' => 'image',
                        'meta' => [
                            'options' => [
                                'maxCount' => 1,
                            ]
                        ]
                    ],
                ],
            ],
        ]);

        $this->assertEquals('foo baz bar', $result->title);
        $this->assertEquals('lorem ipsum', $result->subtitle);
        $this->assertEquals('baz', $result->icon);
        $this->assertEquals('faz', $result->category);
        $this->assertEquals('foo', $result->ui_component);
        $this->assertTrue($result->is_enabled);
        $this->assertTrue($result->drag_and_drop);

    }

    public function testExportToRemote()
    {
        $element = ContentElement::factory()->create(['slug' => 'foo']);
        $element2 = ContentElement::factory()->create();
        ContentElementField::factory()->create([
            'element_id' => $element2->id,
            'child_element_id' => $element->id,
        ]);

        $result = $this->repository()->exportToRemote([$element->id, $element2->id]);

        $this->assertCount(2, $result);
        $this->assertArrayHasKey('id', $result[0]);
        $this->assertArrayHasKey('slug', $result[0]);
        $this->assertArrayHasKey('title', $result[0]);
        $this->assertArrayHasKey('fields', $result[0]);

        $field = $result[1]['fields'][0];
        $this->assertEquals('foo', $field['child_element_id']);

    }

    public function testCanImport()
    {
        ContentElement::factory()->create(['slug' => 'foo']);
        $true = [
            'fields' => []
        ];
        $true2 = [
            'fields' => [
                [
                    'child_element_id' => null,
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];

        $true3 = [
            'fields' => [
                [
                    'child_element_id' => 'foo',
                    'data' => [],
                ]
            ]
        ];

        $false = [
            'fields' => [
                [
                    'child_element_id' => 'foobar',
                    'data' => [],
                ]
            ]
        ];

        $false2 = [
            'fields' => [
                [
                    'child_element_id' => 'foo',
                    'data' => [],
                ],
                [
                    'child_element_id' => 'foobar',
                    'data' => [],
                ],
            ]
        ];

        $this->assertTrue($this->repository()->canBeImported($true));
        $this->assertTrue($this->repository()->canBeImported($true2));
        $this->assertTrue($this->repository()->canBeImported($true3));
        $this->assertFalse($this->repository()->canBeImported($false));
        $this->assertFalse($this->repository()->canBeImported($false2));
    }

    public function testCheckImportValidity()
    {
        ContentElement::factory()->create(['slug' => 'baz-bar']);
        $entry = [
            'slug' => 'foo',
            'fields' => [
                [
                    'child_element_id' => null,
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];
        $allData = [$entry];

        $result = $this->repository()->checkImportEntryValidity($entry, $allData);
        $this->assertCount(0, $result['errors']);

        $entry = [
            'slug' => '',
            'fields' => [
                [
                    'child_element_id' => null,
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];
        $allData = [$entry];

        $result = $this->repository()->checkImportEntryValidity($entry, $allData);
        $this->assertCount(1, $result['errors']);
        $entry = [
            'slug' => 'baz-bar',
            'fields' => [
                [
                    'child_element_id' => null,
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];
        $allData = [$entry];

        $result = $this->repository()->checkImportEntryValidity($entry, $allData);
        $this->assertCount(1, $result['errors']);

        $this->assertCount(1, $result['errors']);
        $entry = [
            'slug' => 'foo',
            'fields' => [
                [
                    'name' => 'Foobar',
                    'child_element_id' => 'foobar',
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];
        $allData = [$entry];

        $result = $this->repository()->checkImportEntryValidity($entry, $allData);
        $this->assertCount(1, $result['errors']);
        $entry = [
            'slug' => 'foo',
            'fields' => [
                [
                    'name' => 'Foobar',
                    'global_content_id' => 'foobar',
                    'element_id' => 2,
                    'data' => [],
                ]
            ]
        ];
        $allData = [$entry];

        $result = $this->repository()->checkImportEntryValidity($entry, $allData);
        $this->assertCount(1, $result['errors']);
    }

    public function testImportRecord()
    {
        ContentElement::factory()->create(['slug' => 'foo-faz']);
        $data = [
            'title' => 'Foo',
            'slug' => 'foo',
            'fields' => [
                [
                    'child_element_id' => 'foo-faz',
                    'name' => 'baz',
                    'slug' => 'baz',
                    'field_type' => 'text'
                ]
            ]
        ];
        $this->assertTrue($this->repository()->importRecord($data));
        $this->assertTrue(ContentElement::query()->where('slug', 'foo')->exists());
    }

    private function repository(): ElementRepository
    {
        return App::make(ElementRepositoryContract::class);
    }
}
