<?php
namespace Battles;

use Battles\Database\Db;

class InventoryItem extends Item
{
    private $present;
    private $owner_id;
    private const TOO_MANY_ITEMS_IN_SLOTS = 'Критическая ошибка: Переполнение слота!';
    private const UNKNOWN_ITEM_TYPE = 'Неизвестный тип предмета!';
    private const REQUIREMENTS_NOT_MET = 'Персонаж не соответствует требованиям!';

    /**
     * InventoryItem constructor.
     *
     * @param $row
     */
    public function __construct($row)
    {
        parent::__construct($row);
        $this->owner_id = $row->owner_id;
        $this->present = $row->present;
    }

    public function printInfo()
    {
        echo $this->getAllInfo();
        if ($this->present) {
            echo "<p style='color: maroon; font-style: italic'>Это подарок от $this->present. Вы не можете передать его кому-либо ещё.</p>";
        }
    }

    public function printImage()
    {
        if (in_array($this->item_type, range(1, 12))) {
            echo <<<HTML
<a href=/main.php?edit=1&dress=$this->item_id title='Надеть'>
    <img src="/i/sh/$this->image" class="item-wrap-normal" alt="">
</a>
HTML;
        } else {
            echo <<<IMG
<img src="/i/sh/$this->image" class="item-wrap-normal" alt="">
IMG;
        }
    }

    public function printControls(){
        // Для кнопок управления под картинкой.
    }

    private function dressStatsChecks(): ?string
    {
        $checkStats = new UserStats($this->owner_id);
        $stat = $checkStats->getFullStats();
        return
            $this->need_strength > $stat->strength
            || $this->need_dexterity > $stat->dexterity
            || $this->need_intuition > $stat->intuition
            || $this->need_endurance > $stat->endurance
            || $this->need_intelligence > $stat->intelligence
            || $this->need_wisdom > $stat->wisdom
                ? true : null;
    }

    /**
     * Одевание предмета из инвентаря в слот.
     * @return bool|string
     */
    public function dressItem()
    {
        $itemInSlot = [];
        if ($this->dressStatsChecks()) {
            return self::REQUIREMENTS_NOT_MET;
        }
        // считаем сколько ОДЕТЫХ предметов в слоте в который мы хотим одеть предмет. 1=просто вещь 1-3=шашни с кольцами
        // Count добавленный в первый запрос возвращает одну строку в любом случае.
        // fetch возвращает одну строку в любом случае.
        $weared = Db::getInstance()->ofetchAll('SELECT dressed_slot FROM inventory WHERE dressed_slot != 0 AND item_type = ? AND owner_id = ?', [$this->item_type, $this->owner_id]);
        $wearedCount = Db::getInstance()->ofetch('select count(dressed_slot) as c from inventory where dressed_slot !=0 and item_type = ? and owner_id = ?', [$this->item_type, $this->owner_id]);
        // Если в слоте есть предмет(ы), забиваем их массив одетых в слот предметов.
        if ($wearedCount) {
            foreach ($weared as $item) {
                $itemInSlot[] = $item->dressed_slot;
            }
        }
        if (in_array($this->item_type, [
            self::ITEM_TYPE_HELMET, self::ITEM_TYPE_ARMOR, self::ITEM_TYPE_LEGS, self::ITEM_TYPE_BOOTS,
            self::ITEM_TYPE_GLOVES, self::ITEM_TYPE_WEAPON, self::ITEM_TYPE_SHIELD, self::ITEM_TYPE_BELT,
            self::ITEM_TYPE_AMULET,
        ])) {
            //работаем с нормальными слотами
            if ($wearedCount->c == 1) {
                //если слот занят, снимаем старый предмет и одеваем новый предмет
                Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = ? AND owner_id = ?', [$itemInSlot[0], $this->owner_id]);
                Db::getInstance()->execute('UPDATE inventory SET dressed_slot = item_type WHERE item_id = ? AND owner_id = ?', [$this->item_id, $this->owner_id]);
            } elseif (!$wearedCount->c) {
                //если слот пуст, одеваем новый предмет
                Db::getInstance()->execute('UPDATE inventory SET dressed_slot = item_type WHERE item_id = ? AND owner_id = ?', [$this->item_id, $this->owner_id]);
            } else {
                /* проверка на переполнение слотов */
                $error = self::TOO_MANY_ITEMS_IN_SLOTS;
                DressedItems::undressAllItems($this->owner_id);
            }
        } elseif ($this->item_type == self::ITEM_TYPE_RING) {
            // работаем с кольцами
            if ($wearedCount->c < 3) {
                // Сравниваем массив колец и массив слотов для колец.
                $emptyRingSlots = array_diff([9, 10, 11], $itemInSlot);
                // Сортируем массив свободных слотов по возрастанию.
                sort($emptyRingSlots);
                // Одеваем предмет в первый свободный слот.
                Db::getInstance()->execute('update inventory set dressed_slot = ? where item_id = ?', [$emptyRingSlots[0], $this->item_id]);
            } elseif ($wearedCount->c == 3) {
                // Cнимаем предмет из последнего слота 11 и одеваем новый предмет
                Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 0 WHERE dressed_slot = 11');
                Db::getInstance()->execute('UPDATE inventory SET dressed_slot = 11 WHERE item_id = ?', $this->item_id);
            } else {
                /* проверка на переполнение слотов */
                $error = self::TOO_MANY_ITEMS_IN_SLOTS;
                DressedItems::undressAllItems($this->owner_id);
            }
        } else {
            $error = self::UNKNOWN_ITEM_TYPE;
        }

        return $error ?? true;
    }

    public static function destroyItem($itemId)
    {
        Db::getInstance()->execute('delete from inventory where dressed_slot = 0 and owner_id = ? and item_id = ?', [$_SESSION['uid'], $itemId]);
    }

    /** Надеюсь, временная заглушка, которая объединяет get_meshok() и другую выдачу одной строкой.
     * @return string
     */
    public static function getWeightData(): string
    {
        $query = 'select sum(weight) as `all`, strength * 4 as max from inventory left join users u on owner_id = id where owner_id = ?';
        $weight = Db::getInstance()->ofetch($query, User::getInstance()->getId());
        $css = $weight->all > $weight->max ? ' style="color:maroon;"' : '';
        return "<span$css>$weight->all / $weight->max</span>";
    }
}