<?php

namespace Mnv\Models\Shop;

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

/**
 * Class Category
 * @package Mnv\Models\Shop
 */
class Category extends Model
{
    protected string $table = 'category';

    protected string $primaryKey = 'categoryId';

    protected string $orderBy = 'orderBy ASC';


    public $optionIds = [];
    public $options = [];

    public function __construct(Request $request)
    {
        $this->id          = $request->get('id');
        $this->data        = $request->get('category', '');
        $this->optionIds   = $request->get('optionIds', '');
        /** options  */
        $this->options = $request->get('options', '');

    }


    private function sortBy()
    {
        if (!empty($this->filter['query'])) {
            connect()->grouped(function($q) {
                $q->like('name', "%" . $this->filter['query'] . "%");
            });
        }
        if (!empty($this->filter['status'])) {
            connect()->where('status', $this->filter['status']);
        }

        connect()->whereNull('parentId',  false);

    }


    public function all($limit, $page)
    {
        $this->sortBy();

        return parent::all($limit, $page);
    }
    public function total()
    {
        $this->sortBy();

        parent::total();
    }


    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'] = connect()->table($this->table)->max('orderBy')->getValue() + 1;
            if ($this->id = $this->insert($data)) {
                return true;
            }
        }
        else {

            return $this->update($data);
        }

        return false;
    }



    /** Удаление */
    public function remove(): bool
    {
        /** удаление свойства */
        if (connect()->table($this->table)->where($this->primaryKey, $this->id)->delete()) {
            connect()->table($this->table)->where('parentId', $this->id)->delete();

            return true;
        }

        return false;
    }


    /** Сортировка */
    public function reorder($featureIds)
    {
        $i = 0;
        foreach ($featureIds as $featureId) {
            $i++;
            connect()->table($this->table)->where($this->primaryKey, $featureId)->update(['orderBy' => $i]);
        }
    }


    /** OPTIONS */

    public function categories(): ?array
    {
        if (!empty($this->id)) {
            return connect($this->table)->where('parentId', $this->id)->orderBy('orderBy')->indexKey($this->primaryKey)->getAllIndexes('array');
        }

        return [];
    }

    public function category(int $optionId)
    {
        if (!empty($optionId)) {
            return connect($this->table)->where($this->primaryKey, $optionId)->get('array');
        }

        return null;
    }

    public function addCategory(array $option): int
    {
        $option['parentId'] = $this->id;
        $option['orderBy'] = 0;

        return connect($this->table)->insert($option);
    }

    /**
     * @param int $optionId
     * @param array $option
     */
    public function updateCategory(int $optionId, array $option): void
    {
        connect($this->table)->where($this->primaryKey, $optionId)->update($option);
    }

    public function removeCategory(int $optionId): void
    {
        connect($this->table)->where($this->primaryKey, $optionId)->delete();
    }



    /**
     * ПОЛУЧИТЬ свойства и опции
     * @return array
     */
    public function getLevelCategorys(): ?array
    {
        return connect($this->table)->select('categoryId, name, type')->orderBy('orderBy ASC')->whereNull('parentId',  false)->getAll('array');

    }

    /** ПОЛУЧИТЬ опции */
    public function getSelectCategorys(): ?array
    {

        if (!empty($this->filter['query'])) {
            connect()->grouped(function($q) {
                $q->like('name', "%" . $this->filter['query'] . "%");
            });
        }
        $options = connect($this->table)->select('categoryId, name, type')->orderBy('orderBy ASC')->whereNull('parentId',  false)->pagination($this->filter['limit'], $this->filter['start'])->getAll('array');
        return collect($options)->map(function ($option) {
            $option['properties'] = connect($this->table)->select('categoryId, name')->where('parentId', $option[$this->primaryKey])->whereNull('parentId',  true)->getAll('array');

            return $option;
        })->all();
    }


    /**
     * ПОЛУЧИТЬ свойства и опции
     * @return array
     */
    public function getOptions(): ?array
    {
        $options = connect($this->table)->select('categoryId, name, type')->orderBy('orderBy ASC')->whereNull('parentId',  false)->getAll('array');
        return collect($options)->map(function ($option) {
            $option['properties'] = connect($this->table)->select('categoryId, name')->where('parentId', $option[$this->primaryKey])->whereNull('parentId',  true)->getAll('array');

            return $option;
        })->all();
    }

//$query = $this->db->query(
//      "SELECT DISTINCT *,
//          (SELECT
//              GROUP_CONCAT(cd1.name ORDER BY level SEPARATOR '&nbsp;&nbsp;&gt;&nbsp;&nbsp;')
//              FROM " . DB_PREFIX . "category_path cp
//              LEFT JOIN " . DB_PREFIX . "category_description cd1
//              ON (cp.path_id = cd1.category_id AND cp.category_id != cp.path_id)
//              WHERE cp.category_id = c.category_id
//              GROUP BY cp.category_id) AS path
//      FROM " . DB_PREFIX . "category c
//      LEFT JOIN " . DB_PREFIX . "category_description cd2 ON (c.category_id = cd2.category_id)
//      WHERE c.category_id = '" . (int)$category_id . "'
//      AND cd2.language_id = '" . (int)$this->config->get('config_language_id') . "'");
    public function getSelect(): ?array
    {
        $categories = connect('category AS c1')
            ->select('c1.categoryId, c1.name, GROUP_CONCAT(c2.name) AS child')
            ->join('category AS c2', 'c1.categoryId', '=', 'c2.parentId')
            ->groupBy('c1.categoryId')
//            ->orderBy('c1.orderBy ASC')
            ->getAll('array');



//        $categories = connect($this->table)->select('categoryId, name')->orderBy('orderBy ASC')->whereNull('parentId',  false)->getAll('array');
//        foreach ($categories as $categoryId => $category) {
//            $categories[$categoryId]['children'] = connect($this->table)->select('categoryId, name')->where('parentId', $category[$this->primaryKey])->whereNull('parentId',  true)->getAll('array');
//        }

        print_r($categories);

        return $categories;
//        return collect($categories)->map(function ($category) {
//            $category
//            $category['parents'] = connect($this->table)->select('categoryId, name')->where('parentId', $category[$this->primaryKey])->whereNull('parentId',  true)->getAll('array');
//
//            return $category;
//        })->all();
    }

    public function getCategories(): ?array
    {
        $categories = connect($this->table)->select('categoryId, name')->orderBy('orderBy ASC')->whereNull('parentId',  false)->getAll('array');
        return collect($categories)->map(function ($option) {
            $option['parents'] = connect($this->table)->select('categoryId, name')->where('parentId', $option[$this->primaryKey])->whereNull('parentId',  true)->getAll('array');

            return $option;
        })->all();
    }


}