<?php

namespace Clevercherry\Backslash4\Models;

use \Clevercherry\Backslash4\Models\Model;
use Illuminate\Support\Str;

class Setting extends Model
{
    protected $attributes = array(
        'options' => '{}',
        'description' => '',
        'group' => ''
    );

    public static function getSetting($slug, $default=null)
    {
        $item = self::where('slug', $slug)->first();

        if(empty($item))
            return $default;
        
        if($item->value==null)
            if($default==null)
                return $item->default;
            else
                return $default;
        //else

        return $item->value;
    }

    /**
     * Returns the Media from the settings JSON
     * @param String $slug      the sluig identifiying the setting
     * @param bool   $first     if false (default) returns an array of media items, if true return only the first media item
     * @return Mediamanager | Array[MediaManager]
     */
    public static function getSettingMedia($slug, $first=false) : MediaManager | Array
    {
        $json = self::getSetting($slug, null);
        
        if(empty($json))
            return []; //return the empty array so iterations can just pass over it

        if($first)
            return \App\Models\MediaManager::getFirstMediaItemFromJson($json);
        //else

        return \App\Models\MediaManager::getMediaItemsFromJson($json);
    }

    /**
     * Override bs4\Model as settings do not have blocks
     */
    public function hasBlocks()
    {
        return false;
    }

    /**
     * Get the route Url from the path but trapped for an error
     * @return String | null
     */
    public function getRoutePath() : string | null
    {
        $url = null;
        try {
            $url = Route($this->value);
        } catch (\Throwable $th) {
            //throw $th;
        }

        return $url;
    }
    
    /**
     * get a list for a select box based upon field_name
     * see product model for an example override
     */
    public function getChooseOptions($field_name)
    {
        // see product model for an example override
        if($field_name=='input')
            return [ '' => 'Select an Input Type...',
                     'text' => 'Text',
                     'richtexteditor' => 'Rich Text Editor',
                     'text-area' => 'Text Area',
                     'choose-options' => 'Select',
                     'data-list' => 'Combo Box (Data-List)',
                     'check-box' => 'CheckBox',
                     'switch' => 'Switch',
                     'number' => 'Number',
                     'money' => 'Money',
                     'media' => 'Media Item',
                     'media-gallery' => 'Media Gallery',
                     'date-time' => 'Date & Time',
                     'link-route:readonly' => 'Read Only Link, from a route, Button',
                     'link:readonly' => 'Read Only Link, Button',
                     'readonly' => 'Test displayed, readonly/disabled',
                     'hidden' => 'Not displayed, disabled'
                   ];

        return [];
    }

    /**
     * by default return the options value as an array
     * you may choose to override this and provide dynamic data dependent upon the slug of the setting
     */
    public function getOptionsArray()
    {
        return json_decode($this->options, true);
    }

    /**
     * get a list for a input/datalist box based upon field_name
     */
    public function getDataList($field_name)
    {
        if($field_name=='group')
        {
            $list=[];
            foreach(self::getGroups() as $group)
                $list[$group->group] = Str::headline($group->group);
            
            return $list;
        }
        // see product model for an example override
        return [];
    }

    /**
     * get a list for a input/datalist box based upon field_name
     */
    public function getTagList($field_name)
    {
        if($field_name=='group')
        {
            $list=[];
            foreach(self::getGroups() as $group)
                $list[$group->group] = Str::headline($group->group);
            
            return $list;
        }
        // see product model for an example override
        return [];
    }

    public static function getGroups()
    {
        return self::selectRaw('`group`, min(`order`) as o2')
                    ->groupBy('group')
                    ->orderByRaw("min(`order`)")->get();
    }

    public static function translateGroupName($groupName)
    {
        if(str_contains($groupName, 'apis'))
            return str_replace('Apis', 'APIs', Str::headline($groupName));
        
        return Str::headline($groupName);
    }

    /**
     * return 'required' if this firld is required - default is required
     * override in the model or model in your app
     */
    public function getFieldRequired($field_name)
    {
        if(in_array($field_name, ['default', 'description', 'value', 'options']))
            return '';
        //else

        if(in_array($field_name, ['input', 'slug']))
            return 'required';
        //else

        return parent::getFieldRequired($field_name);
    }


    public function getFieldType($field_name, $item=null)
    {
        switch($field_name) {
            case 'options':
                return 'text-area';
            case 'description':
                return 'text-area';
            case 'required':
                return 'switch';
            case 'order':
                return 'number';
            // case 'group':
            //     return 'tag-select';
        }

        return parent::getFieldType($field_name, $item);
    }

    public function getOption($optionName, $default=null)
    {
        if(empty($this->options))
            return $default;
        
        $json = json_decode($this->options,false);

        if(isset($json->$optionName))
            return $json->$optionName;

        //else
        return $default;
    }

    //no front end routes
    public static function getFrontEndRoute($default, $is_index=false) : String | null
    {
        return null;
    }

}