<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Mtc\ContentManager\Models\ContentElementField;
use Mtc\ContentManager\Models\Template;
use Mtc\MercuryDataModels\ContentElement;

class ConvertTemplateToSeed extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'content:convert-template-to-seed {template} {--tenant=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create a seed from content template';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        if (!$this->option('tenant')) {
            $this->output->error('Please provide a tenant');
            return Command::FAILURE;
        }

        tenancy()->initialize($this->option('tenant'));
        /** @var Template $template */
        $template = Template::query()->findOrFail($this->argument('template'));
        try {
            $this->writeFile($this->loadReplacements($template), $template);
            $this->output->success($this->className($template) . ' Seeder Generated');
            $this->output->warning('Please make sure to test and fix any PSR issues on file');
        } catch (\Exception $exception) {
            $this->output->success('Failed with error: ' . $exception->getMessage());
            return Command::FAILURE;
        }
        return Command::SUCCESS;
    }

    private function loadReplacements(Template $template): array
    {
        $template->load([
            'elements.element',
            'elements.globalContent',
        ]);
        $elements = ContentElement::query()
            ->with('fields.childElement')
            ->whereIn('id', $this->getRecursiveElementsForTemplateFields($template->elements->pluck('element_id')))
            ->get();
        return [
            'class' => $this->className($template),
            'templateData' => view('seed-generator.template.data', compact('template'))->render(),
            'elementList' => view('seed-generator.template.content-elements', compact('elements'))->render(),
            'templateElementList' => view('seed-generator.template.elements', compact('template'))->render(),
        ];
    }

    private function writeFile(array $replacements, Template $template)
    {
        $source = File::get(resource_path('stubs/template-seeder.stub'));
        $keys = array_map(fn ($value) => "{{ $value }}", array_keys($replacements));
        $content = str_replace($keys, $replacements, $source);
        File::put('database/seeders/Tenant/' . $this->className($template) . '.php', $content);
    }

    private function className(Template $template)
    {
        return str_replace(' ', '', Str::title($template->name)) . 'Seeder';
    }

    private function getRecursiveElementsForTemplateFields(Collection $elementIds): Collection
    {
        $subElementIds = collect();
        $childElementIds = ContentElementField::query()
            ->whereIn('element_id', $elementIds)
            ->whereNotNull('child_element_id')
            ->pluck('child_element_id');

        if ($childElementIds->isNotEmpty()) {
            $subElementIds = $this->getRecursiveElementsForTemplateFields($childElementIds);
        }

        return $elementIds->merge($childElementIds)
            ->merge($subElementIds);
    }
}
