<?php

namespace Wizzard\MagicForger\Generator;

use Illuminate\Support\Str;

trait Replacer
{
    /**
     * Prefix and Suffix for controller.
     * Usage is up to the user.
     *
     * @var string
     */
    protected $controller_prefix = "";


    /**
     * Prefix and Suffix for controller.
     * Usage is up to the user.
     *
     * @var string
     */
    protected $controller_suffix = "Controller";


    /**
     * Finds all places in a string that could be replaced.
     * Returns an array of all potential replacements as they
     * appear in the target.
     */
    public function get_all_inserts(string $target): array
    {
        //find all the matches to our expected syntax
        $matches = [];
        preg_match_all('/{{[\sa-zA-Z\-_]+}}/', $target, $matches);
        // sort the array and return unique values
        sort($matches[0]);
        return array_values(array_unique($matches[0]));
    }


    public function apply_replacements(string $target): string
    {
        $inserts = $this->get_all_inserts($target);
        $available_replacements = $this->get_available_replacements();

        $target = str_replace(
            array_keys($available_replacements),
            $available_replacements,
            $target
        );

        return $target;
    }
    /**
     * @return array<string,mixed>
     */
    public function get_available_replacements()
    {
        $table_name = $this->getTableInput();
        $replacements = [
                    "{{ class }}" => $this->getClassName($table_name),
                    "{{ model }}" => $this->model_name($table_name),
                    "{{ modelVariable }}" => $this->model_variable($table_name),
                    "{{ namespace }}" => $this->{'get' . $this->type . 'Namespace'}(),
                    "{{ namespacedModel }}" => $this->getModelNamespace(),
                    "{{ requestUses }}" => $this->getRequestUses($table_name),
                    "{{ rootNamespace }}" => $this->getRootNamespace(),
                    "{{ storeRequest }}" => $this->store_request_name($table_name),
                    "{{ tableName }}" => $table_name,
                    "{{ updateRequest }}" => $this->update_request_name($table_name),
        ];

        return $replacements;
    }

    ////////////////////////////////////////////
    //				Internals and Classes   				//
    ////////////////////////////////////////////

    /**
     * Model names are generated in uppercase first Camel case
     */
    public function model_name(string $name): string
    {
        return Str::singular(Str::studly($name));
    }

    /**
     * Model variable is standardly just a singular version of the table name
     */
    public function model_variable(string $name): string
    {
        return Str::singular($name);
    }

    /**
     * Controller names are generated in uppercase first Camel case
     * and wrapped in the prefix and suffix
     */
    public function controller_name(string $name): string
    {
        return $this->controller_prefix .
            $this->model_name($name) .
            $this->controller_suffix;
    }

    public function store_request_name(string $name): string
    {
        return 'Store' . $this->model_name($name);
    }

    public function update_request_name(string $name): string
    {
        return 'Update' . $this->model_name($name);
    }


    ////////////////////////////////////////////
    //							Namespaces			   				//
    ////////////////////////////////////////////

    public function getRootNamespace()
    {
        return $this->laravel->getNamespace();
    }

    public function getModelNamespace()
    {
        return $this->getRootNamespace() . 'Models';
    }

    public function getControllerNamespace()
    {
        return $this->getRootNamespace() . 'Http\\Controllers';
    }

    public function getRequestNamespace(string $name)
    {
        return $this->getRootNamespace() . 'Http\\Requests\\' . $this->model_name($name);
    }
    /**
     * @return string
     */
    public function getRequestUses(string $name)
    {
        return implode("\n", [
            "use " . $this->getRequestNamespace($name) . '\\' . $this->store_request_name($name),
            "use " . $this->getRequestNamespace($name) . '\\' . $this->update_request_name($name),
        ]);
    }


    ////////////////////////////////////////////
    //				Language and Presentables				//
    ////////////////////////////////////////////

    /**
     * Breaks up a string and makes it human readable
     *
     * This function assumes that the inputted name is camel case
     */
    public function human_readable(string $name): string
    {
        return Str::title(Str::replace('_', ' ', $name));
    }

    /**
     * Breaks up a string and makes it human readable and lowecase
     *
     * This function assumes that the inputted name is camel case
     */
    public function human_readable_lc(string $name): string
    {
        return Str::lower($this->human_readable($name));
    }
}

class Replacer
{
    /**
     * @return void
     */
    public function get_available_replacements(): array
    {
    }

    public function getRequestUses(): string
    {
    }
}
