<?php

namespace Ignite\Core\Database\Seeders;

use Ignite\Core\Contracts\Repositories\PageRepository;
use Ignite\Core\Entities\Page;
use Illuminate\Support\Carbon;

/**
 * php artisan db:seed --class="Ignite\Core\Database\Seeders\PageTableSeeder"
 * php artisan module:seed Core
 */
class PageTableSeeder extends AbstractSeeder
{
    /**
     * The name of the data file.
     *
     * @var string
     */
    protected $file = 'core_page.json';

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        parent::run();

        $pageRepository = app(PageRepository::class);
        $strategy = $this->strategy('json', [
            'filepath' => $this->getFilepath($this->file)
        ]);

        /** @var \Illuminate\Support\Collection $sources */
        $sources = $strategy->run()->sortBy('position');

        foreach ($sources as $source) {
            try {
                $this->seedRow($pageRepository, $source);
            } catch (\Exception $e) {
                echo $e->getMessage() . PHP_EOL;
                continue;
            }
        }
    }

    /**
     * Content only valid if newer than last update, otherwise it may too old to use.
     * To prevent accidental overwrite of existing newer content.
     *
     * @param  array     $data
     * @param  Page|null $page
     * @return boolean
     */
    protected function isStillValidUpdate(array $data, ?Page $page = null): bool
    {
        if (! $page) {
            return true;
        }

        $validIfLastUpdateBefore = $data['_valid_if_last_update_before_'] ?? null;

        return (null === $validIfLastUpdateBefore
            || Carbon::parse($validIfLastUpdateBefore) > $page->updated_at
        );
    }

    /**
     * @param  PageRepository $pageRepository
     * @param  array          $source
     */
    protected function seedRow(PageRepository $pageRepository, array $source)
    {
        $page = Page::where([
            "code" => $source['code'],
            "locale" => $source['locale'],
        ])
            ->first();

        $isStillValidUpdate = $this->isStillValidUpdate($source, $page);
        unset($source['_valid_if_last_update_before_']);

        if (isset($source['_delete_']) && true === $source['_delete_']) {
            if ($page) {
                $page->delete();
            }
        } elseif ($page) {
            if (! $isStillValidUpdate) {
                return;
            }
            unset($source['id']);
            $pageRepository->update($page->id, $source);
        } else {
            $source['published_at'] = now();
            $pageRepository->create($source);
        }
    }
}
