<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

require_once  __DIR__ . '/../ViisonSetArticlesUtil.php';

MLFilesystem::gi()->loadClass('Shopware_Model_Product');

/**
 * Class ML_ViisonSetArticles_Model_Order
 * @Shopware\noEncryption
 */
// @codingStandardsIgnoreLine
class ML_ViisonSetArticles_Model_Product extends ML_Shopware_Model_Product
{

    /**
     * Overrides parent getSock method: returns new calculated stock for set articles (use parent otherwise)
     *
     * @return int
     */
    public function getStock()
    {
        // This also checks if the SetArticles plugin is installed and active
        if ($this->isSetArticleByArticleDetail($this->getArticleDetail())) {
            return $this->getCalculatedInstockFromSetArticleDetailId($this->getArticleDetail()->getId());
        } else {
            $oldInstock = parent::getStock();

            return $oldInstock;
        }
    }

    /**
     * Overrides parent getWeight method: returns new calculated weight for set articles (use parent otherwise)
     *
     * @return array
     */
    public function getWeight()
    {
        $result = parent::getWeight();
        // This also checks if the SetArticles plugin is installed and active
        if ($this->isSetArticleByArticleDetail($this->getArticleDetail())) {
            $weight = $this->getCalculatedWeightFromSetArticleDetailId($this->getArticleDetail()->getId());
            $result['Value'] = $weight;

            return $result;
        } else {
            return $result;
        }
    }

    /**
     * Calculates the actual weight of a given set article (by Article/Detail id).
     * Quantity (in set) * weight of each sub article is summed up.
     *
     * @param int $setArticleDetailId
     * @return int
     */
    private function getCalculatedWeightFromSetArticleDetailId($setArticleDetailId)
    {
        $sql = 'SELECT SUM(sad.weight * savs.quantity) as weight
                FROM s_articles_details as sad
                LEFT JOIN s_articles_viison_setarticles as savs ON sad.id = savs.articledetailid
                WHERE savs.setid = :setArticleId';
        $parameters = [
            'setArticleId' => $setArticleDetailId,
        ];
        $dbalConnection = Shopware()->Container()->get('models')->getConnection();
        $calculatedWeight = $dbalConnection->fetchAssoc($sql, $parameters);
        $result = $calculatedWeight['weight'] ? $calculatedWeight['weight'] : 0;

        return $result;
    }

    /**
     * Calculates the actual instock of a given set article (by Article/Detail id).
     * Returns 0 if no instock could be calculated.
     *
     * @param int $setArticleDetailId
     * @return int
     */
    private function getCalculatedInstockFromSetArticleDetailId($setArticleDetailId)
    {
        $sql = 'SELECT MIN(sad.instock DIV savs.quantity) as instock
                FROM s_articles_details as sad
                LEFT JOIN s_articles_viison_setarticles as savs ON sad.id = savs.articledetailid
                WHERE savs.setid = :setArticleId';
        $parameters = [
            'setArticleId' => $setArticleDetailId,
        ];
        $dbalConnection = Shopware()->Container()->get('models')->getConnection();
        $calculatedInstock = $dbalConnection->fetchAssoc($sql, $parameters);
        $result = $calculatedInstock['instock'] ? $calculatedInstock['instock'] : 0;

        return $result;
    }

    /**
     * @param Shopware\Models\Article\Detail $articleDetail
     * @return bool
     */
    private function isSetArticleByArticleDetail($articleDetail)
    {
        $util = new ViisonSetArticlesUtil();

        return (
            $util->isSetArticlesInstalledAndActive() &&
            $articleDetail && $articleDetail->getAttribute() &&
            $articleDetail->getAttribute()->getViisonSetarticleActive());
    }
}
