<?php

namespace Mnv\Models\Shop;

use Mnv\Core\Model;

use Mnv\Core\Test\Logger;
use Mnv\Core\Uploads\ImageSizes;
use Mnv\Http\Request;
use Mnv\Models\Exceptions\NoContentException;
use Mnv\Models\Exceptions\NotInsertContentException;
use Mnv\Models\Exceptions\NotUpdateContentException;
use Mnv\Models\Exceptions\NotContentApproveException;

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

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

    /** @var string  */
    protected string $table_image = 'product_images';

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

    protected string $orderBy = 'publishedOn DESC';

    /** @var string  */
    protected string $columns = 'productId, title, alias, sectionId, isFeatured, url, publishedOn, publishedEnd, orderBy, status, price, quantity, enableGallery, stock_status_id, addedBy, modifiedBy, sku, show_contact';

    public $field;

    /** @var array $image */
    public $image = array();

    /** @var int $imageId */
    public int $imageId;

    public string $typeContent;

    public $contentIds = [];

    public $subtracts = array(
        '0' => 'Нет',
        '1' => 'Да',
    );

    public $specials = array(
        '0' => 'Выбрать особенность товара',
        'new' => 'Новинка',
        'sale' => 'Акция',
    );


    public $stock_status = array(
        'instock'   => 'В наличии',
        'outstock'  => 'Нет в наличии',
        'preorder'  => 'Предзаказ',
    );

    public $show_contacts = array(
        'M'   => 'Менеджер',
        'P'   => 'Заказчик',
    );

    public function __construct(Request $request)
    {
        $this->id           = $request->get('id');                     // getRequestVar('id'),
        $this->data         = $request->get('product', '');     // getRequestVar('product', '', true),
        $this->field        = $request->get('field', '');
        $this->contentIds   = $request->get('productIds', '');

    }

    /**
     * фильтрация / сортировка контента
     */
    protected function sorting(): void
    {
        global $SECTIONS;

        connect()->where('type', 'ordering');

        if (!empty($this->filter['query'])) {
            connect()->grouped(function($q) {
                $q->like('sku', "%" . $this->filter['query'] . "%")->orLike('productId', "%" . $this->filter['query'] . "%")->orLike('title', "%" . $this->filter['query'] . "%")->orLike('content', "%" . $this->filter['query'] . "%")->orLike('keywords',"%" . $this->filter['query'] . "%");
            });
        }

        if (!empty($this->filter['status'])) connect()->where('status', $this->filter['status']);

        if (!empty($this->filter['section']) && !empty($SECTIONS[$this->filter['section']])) {
            $sectionIds = array($this->filter['section']);
            if (!empty($SECTIONS[$this->filter['section']]['allChildren'])) {
                $sectionIds = array_merge($sectionIds, $SECTIONS[$this->filter['section']]['allChildren']);
            }
            connect()->in('sectionId', $sectionIds);
        }

        if (!empty($this->filter['dateStart']) && !empty($this->filter['dateEnd'])) {
            connect()->between('publishedOn', $this->filter['dateStart'], $this->filter['dateEnd']);
        }

    }

    /** Получение */
    public function all($limit, $page)
    {
        /** фильтрация / сортировка */
        $this->sorting();

        return parent::all($limit, $page);
    }

    public function total(): void
    {
        /** фильтрация / сортировка */
        $this->sorting();

        parent::total();
    }

    /**
     * Проверка на совпадение и получение fileName
     *
     * @param string|null $fileName
     * @return int|mixed|string|null
     */
    public function checkFileName(?string $fileName)
    {
        if (empty($fileName)) {
            $maxId = $this->getMaxValue($this->primaryKey);
            return $maxId ? $maxId + 1 : 1;
        }

//        if (!empty($this->id)) connect()->where($this->primaryKey,'<>', $this->id);
//        if ($fileName = connect($this->table)->select('fileName')->where('LOWER(fileName)', strtolower($fileName))->getValue()) {
//            return $fileName;
//        }
//
//        return null;
    }

    /**
     * @throws NotUpdateContentException
     * @throws NotInsertContentException
     */
    public function prepare(array $data, int $managerId): bool
    {

        if (!empty($this->id)) {
            $modifiedBy = connect()->table($this->table)->select('modifiedBy')->where('productId', $this->id)->getValue();
            if ($modifiedBy == 0) $data['modifiedBy'] = $managerId;
        } else {
            $data['modifiedBy'] = $managerId;
        }

        $data['modifiedOn']   = gmdate('Y-m-d H:i:s');
        $data['publishedOn']  = adjustTime(date('Y-m-d H:i:s', strtotime($data['publishedOn'])),  true);
        $data['type']         = 'ordering';

        $sku = 1;
        $lastSku = connect($this->table)->max('ABS(sku)')->where('type', 'ordering')->getValue();
        if ($lastSku) {
            $sku = $lastSku + 1;
        }

        $data['sku'] = $sku; //str_pad($sku, 9, '0', STR_PAD_LEFT);

        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)) {

                Logger::init()->info("Добавлен новый контент «" . $data['title'] . "»", $managerId)->save();
                return true;
            }
            Logger::init()->error("Ошибка при добавление контента «" . $data['name'] . "»", $managerId)->save();

            throw new NotInsertContentException();
        }
        else {

            if ($this->update($data)) {

                Logger::init()->info("В контент «" . $data['title'] . "» были внесены изменения", $managerId)->save();
                return true;
            }
            Logger::init()->error("Ошибка при редактирование контента «" . $data['title'] . "»", $managerId)->save();

            throw new NotUpdateContentException();
        }

    }

    /**
     * Удаление контента
     *
     * @return bool
     */
    public function remove(): bool
    {
        if (parent::remove()) {
            connect($this->table_image)->where($this->primaryKey, $this->id)->delete();

            return true;
        }

        return false;
    }

    /**
     * Обновление статуса
     *
     * @return bool
     * @throws NoContentException
     * @throws NotContentApproveException
     */
    public function approve(): bool
    {
        if ( !empty($this->id) && $this->data = $this->get()) {
            if (connect($this->table)->where($this->primaryKey, $this->id)->update(['status' => 'V'])) {
                return true;
            }
            throw new NotContentApproveException();
        }

        throw new NoContentException();
    }

    /**
     * Групповые действия
     * @param $group_action
     */
    public function group($group_action): void
    {
        if ($group_action === 'status') {
            if ( $this->data = $this->get()) {
                $contentUpdate['status'] = ($this->data['status'] === 'V') ? 'H' : 'V';
                $this->statusContent($contentUpdate);
            }

        } else if ($group_action === 'remove') {
            if ($this->data = $this->get()) {
                $this->removeContent();
            }
        }
    }

    /**
     * Обновление статуса товара
     *
     * @param $contentUpdate
     * @return bool
     */
    public function statusContent($contentUpdate): bool
    {
        if (connect($this->table)->where($this->primaryKey, $this->id)->update($contentUpdate)) {
            return true;
        }

        return false;
    }

    /** Удаление товара */
    public function removeContent(): bool
    {
        /** удаление контента и удаление записей из базы данных прикрепленных картинок и комментариев к этому контенту */
        if (connect()->table($this->table)->where($this->primaryKey, $this->id)->delete()) {
            connect()->table('product_images')->where($this->primaryKey, $this->id)->delete();

            return true;
        }

        return false;
    }


    /**
     * получение информации о пользователях, создавших и изменивших контент
     * getting info about users who created and modified the content
     */
    public function gettingUsers($product)
    {
        if (isset($product['addedBy'], $product['modifiedBy'])) {
            $managers = connect('users')->select('userId, loginName, fullName')->in('userId', [$product['addedBy'], $product['modifiedBy']])->indexKey('userId')->getAllIndexes('array');
            $product['addedBy']    = !empty($managers[$product['addedBy']]) ? $managers[$product['addedBy']] : unknownUser();
            $product['modifiedBy'] = !empty($managers[$product['modifiedBy']]) ? $managers[$product['modifiedBy']] : unknownUser();
//            $product['addedOn']    = adjustTime($product['addedOn'], false, 'd.m.Y H:i');
//            $product['modifiedOn'] = adjustTime($product['modifiedOn'], false, 'd.m.Y H:i');
        }

        return $product;
    }

}