<?php

namespace Mnv\Models;

use Mnv\Core\Model;
use Mnv\Http\Request;

/**
 * Class TypeContent
 * @package Mnv\Models
 */
class TypeContent extends Model
{

    /** @var string */
    protected string $table = 'type_content';

    /** @var string  */
    protected string $primaryKey = 'typeId';

    /** @var string  */
    protected string $orderBy = 'orderBy ASC';

    public $groupIds = array();
    public $typeIds = array();

    public int $fieldId;
    public $field = array();
    public $fields = array();


    public function __construct(Request $request)
    {
        $this->id       = (int)$request->get('id');
        $this->data     = $request->get('type');
        $this->groupIds = $request->get('groupIds');
        $this->typeIds  = $request->get('ids');
        $this->field    = $request->get('field');
    }


    public function getPrivileges()
    {
        $this->data['privilege'] = connect()->table('user_group_privileges')->select('groupId')
            ->where('privilege', $this->data['fileName'])
            ->indexKey('groupId')
            ->valueKey('groupId')
            ->getAllIndexes();
    }
    /**
     * Проверка на совпадение и получение fileName
     *
     * @param string|null $fileName
     * @return mixed|string|null
     */
    public function checkFileName(?string $fileName)
    {
        if (!empty($this->id)) {
            connect()->where($this->primaryKey,'<>', $this->id);
        }

        if ($fileName = connect()->table($this->table)->select('fileName')->where('LOWER(fileName)', strtolower($fileName))->getValue()) {
            return $fileName;
        }

        return null;
    }


    public function prepare(array $data, int $managerId): bool
    {

        $data['modifiedBy']   = $managerId;
        $data['modifiedOn']   = gmdate('Y-m-d H:i:s');

        if (empty($this->id)) {

            $data['addedBy']        = $managerId;
            $data['addedOn']        = gmdate('Y-m-d H:i:s');
            $data['orderBy']        = $this->getMaxValue('orderBy') + 1;

            if ($this->id = $this->insert($data)) {
                $this->privileges($data['fileName']);
                $this->generateMenu();
                return true;
            }
        }
        else {

            if ($this->update($data)) {
                $this->privileges($data['fileName']);
                $this->generateMenu();

                return  true;
            }
        }

        return false;
    }


    private function privileges($privilege): void
    {
        if (!empty($this->groupIds)) {
            connect()->table('user_group_privileges')->where('privilege', $privilege)->delete();
            foreach ($this->groupIds as $groupId) {
                connect()->table('user_group_privileges')->insert([
                    'groupId'   => $groupId,
                    'privilege' => $privilege
                ]);
            }

        }
    }

    public function remove(): bool
    {
        if ($typeContent = connect()->table($this->table)->where($this->primaryKey, $this->id)->get('array')) {

            connect()->table($this->table)->where($this->primaryKey, $this->id)->delete();
            if ($fields = connect()->table('type_content_fields')->where($this->primaryKey, $this->id)->getAll('array')) {

                // удалить поля
                connect()->table('type_content_fields')->where($this->primaryKey, $this->id)->delete();

                foreach ($fields as $field) {
                    // удалить value
                    connect()->table('type_content_field_data')->where('fileName', $field['fileName'])->delete();
                    // удалить property
                    connect()->table('type_content_field_property')->where('fieldId', $field['fieldId'])->delete();
                }
            }

            // получаем контент
            if ($contentIds = connect()->table('articles')->select('articleId')->where('typeContent', $typeContent['fileName'])->indexKey('articleId')->valueKey('articleId')->getAllIndexes()) {
                // удалить контент
                connect()->table('articles')->where('typeContent', $typeContent['fileName'])->delete();
                // удаляем прикрепленные картинки
                connect()->table('article_images')->in('articleId', $contentIds)->delete();
            }

            $this->generateMenu();

            return true;
        }

        return false;
    }



    public function status(): bool
    {
        if (!empty($this->id) && $oldStatus = connect()->table($this->table)->select('status, fileName')->where($this->primaryKey, $this->id)->get('array')) {
            $update['status'] = ($oldStatus['status'] == 'V') ? 'H' : 'V';
            connect()->table($this->table)->where($this->primaryKey, $this->id)->update($update);
            $this->generateMenu();
            $this->status = $update['status'];

            return true;
        }

        return false;
    }


    private function generateMenu(): bool
    {
        $url_menu_file = GLOBAL_ROOT . "/admin/menu/menu.json";

        $menu = json_decode(file_read($url_menu_file), true);
        $newItems = connect()->table($this->table)->select('name, fileName')->orderBy('orderBy ASC')->where('status', 'V')->getAll('array');

        foreach ($menu as $key => $item) {

            if (in_array('contents', $item['activeItems'], true)) {
                $contents = array();
                foreach ($newItems as $newItem) {
                    if (array_search($newItem['fileName'], $item['children']) !== false) {
                        continue;
                    } else {
                        $contents[] = [
                            'name'      => $newItem['name'],
//                            'icon'      => 'ph-newspaper',
                            'fileName'  => $newItem['fileName']
                        ];
                    }
                }

                $menu[$key]['children'] = $contents;

                $activeItems = array('contents');
                foreach($contents as $content) {
                    $activeItems[] = $content['fileName'];
                }

                $menu[$key]['activeItems'] = $activeItems;
            }
        }

        $json_menu = json_encode($menu, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
        if ( $fh = fopen($url_menu_file, 'w') ) {
            fwrite($fh, $json_menu);
            fclose($fh);

            $this->generatePermissions();

            return true;
        }

        return false;
    }

    public function generatePermissions(): bool
    {
        $modulesPermissions = include GLOBAL_ROOT.'/admin/config/modules.permissions.inc.php';
        $newItems = connect()->table($this->table)->select('name, fileName')->orderBy('orderBy ASC')->where('status', 'V')->getAll('array');
        $newPermissions = array();

        foreach ($modulesPermissions as $controller => $modulePermission)  {
            $newPermissions[$controller] = $modulePermission;
            if ($controller == 'ContentsAdmin') {
                $activeItems = array();
                foreach($newItems as $content) {
                    $activeItems[] = $content['fileName'];
                }
                $newPermissions[$controller] = $activeItems;
            }
            if ($controller == 'ContentAdmin') {
                $activeItems = array();
                foreach($newItems as $content) {
                    $activeItems[] = mb_substr($content['fileName'], 0, -1);
                }
                $newPermissions[$controller] = $activeItems;
            }
        }

        $permissionExport = "<?php\r\n";
        $permissionExport .= "return \$modules_permissions = ". var_export($newPermissions, true) . ";\r\n";
        $permissionExport .= "?>";

        if ( $fh = fopen(GLOBAL_ROOT.'/admin/config/modules.permissions.inc.php', 'w') ) {
            fwrite($fh, $permissionExport);
            fclose($fh);

            return true;
        }
        return false;
    }



    /** STATIC METHODS */


    public static function selectTypeContents(string $orderBy, string $indexKey, string $valueKey): ?array
    {
        return connect()->table('type_content')->orderBy($orderBy)->where('status', 'V')->indexKey($indexKey)->valueKey($valueKey)->getAllIndexes('array');
    }

    public static function getTypeContentValue(string $field, string $fileName): ?string
    {
        return connect()->table('type_content')->select($field)->where('fileName', $fileName)->getValue();
    }

}