<?php
namespace Hilco\Models;

/**
 * Hilco\Models\PromotionItemQuantityTrigger
 * @property-read integer $id
 * @property integer $minimum_quantity
 * @property integer $maximum_quantity
 * @property boolean $any_product
 * @property integer $almost_qualified
 * @property integer $commit_sequence
 */
class PromotionItemQuantityTrigger extends PromotionTriggerDetails {
    protected $table = 'PromotionItemQuantityTriggers';
    protected $fillable = ['minimum_quantity', 'maximum_quantity', 'any_product', 'almost_qualified', 'commit_sequence'];

    public function promotion() {
        return $this->morphToMany(Promotion::class, 'trigger',
                                    'PromotionTriggers', 'promotion_id',
                            'promotionitemquantitytrigger_id');
    }

    public function hasAlmostQualifyingField() {
        return true;
    }

    public function webGroups() {
        return $this
            ->morphedByMany(WebGroup::class, 'product',
                'PromotionItemQuantityTrigger_Product', 'promotionitemquantitytrigger_id')
            ->withPivot(['excluded'])
            ->whereNull('PromotionItemQuantityTrigger_Product.deleted_at')
            ;
    }

    public function webCategories() {
        return $this
            ->morphedByMany(WebCategory::class, 'product',
                'PromotionItemQuantityTrigger_Product', 'promotionitemquantitytrigger_id')
            ->withPivot(['excluded'])
            ->whereNull('PromotionItemQuantityTrigger_Product.deleted_at')
            ;
    }

    public function webCollections() {
        return $this
            ->morphedByMany(WebCollection::class, 'product',
                'PromotionItemQuantityTrigger_Product', 'promotionitemquantitytrigger_id')
            ->withPivot(['excluded'])
            ->whereNull('PromotionItemQuantityTrigger_Product.deleted_at')
            ;
    }

    public function webFamilies() {
        return $this
            ->morphedByMany(WebFamily::class, 'product',
                'PromotionItemQuantityTrigger_Product', 'promotionitemquantitytrigger_id')
            ->withPivot(['excluded'])
            ->whereNull('PromotionItemQuantityTrigger_Product.deleted_at')
            ;
    }

    public function webParts() {
        return $this
            ->morphedByMany(WebPart::class, 'product',
                'PromotionItemQuantityTrigger_Product', 'promotionitemquantitytrigger_id')
            ->withPivot(['excluded'])
            ->whereNull('PromotionItemQuantityTrigger_Product.deleted_at')
            ;
    }

    public function getRelationForProductTableType($tableType) {
        if($tableType === 'webFamily' || $tableType === 'webCategory') {
            $relationName = substr($tableType, 0, -1);
            $relationName .= 'ies';
        } else {
            $relationName = $tableType . 's';
        }
        return $this->$relationName();
    }

    public function isTriggered(Customer $soldToCustomer, $webCartItems, $distinctPartInfo = [])
    {
        $totalPartQuantity = $this->getCurrentQualifyingCartTotal($soldToCustomer, $webCartItems, $distinctPartInfo);

        return $totalPartQuantity >= $this->minimum_quantity && ($this->maximum_quantity == 0 || $totalPartQuantity <= $this->maximum_quantity);
    }

    public function isAlmostQualifying(Customer $soldToCustomer, $webCartItems, $distinctPartInfo = []) {
        $almostQualifyingCount = $this->getCurrentQualifyingCartTotal($soldToCustomer, $webCartItems, $distinctPartInfo);
        return ($almostQualifyingCount >= $this->almost_qualified) ?
                    $this->minimum_quantity - $almostQualifyingCount : -1;
    }

    public function getCurrentQualifyingCartTotal(Customer $soldToCustomer, $webCartItems, $distinctPartInfo = []) {
        $totalPartQuantity = 0;

        if (!$this->any_product) {
            $triggerWebGroups = $this->webGroups;
            $triggerWebCategories = $this->webCategories;
            $triggerWebCollections = $this->webCollections;
            $triggerWebFamilies = $this->webFamilies;
            $triggerWebParts = $this->webParts;

            foreach ($webCartItems as $webCartItem) {
                $webPartToCheck = $webCartItem->webPart;

                if (isset($webPartToCheck)) {
                    foreach ($triggerWebParts as $triggerWebPart) {
                        if ($triggerWebPart->id == $webPartToCheck->id && $triggerWebPart->pivot->excluded == 0) {
                            $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
                            continue 2; // continue to next $webCartItem
                        }
                    }

                    $webFamilyToCheck = $webPartToCheck->webFamily;

                    if (isset($webFamilyToCheck)) {
                        foreach ($triggerWebFamilies as $triggerWebFamily) {
                            if ($triggerWebFamily->id == $webFamilyToCheck->id && $triggerWebFamily->pivot->excluded == 0) {
                                $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
                                continue 2;
                            }
                        }

                        foreach ($webFamilyToCheck->webCollections as $webCollectionToCheck) {
                            foreach ($triggerWebCollections as $triggerWebCollection) {
                                if ($triggerWebCollection->id == $webCollectionToCheck->id && $triggerWebCollection->pivot->excluded == 0) {
                    $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
                                    continue 3;
                                }
                            }

                            foreach ($webCollectionToCheck->webCategories as $webCategoryToCheck) {
                                foreach ($triggerWebCategories as $triggerWebCategory) {
                                    if ($triggerWebCategory->id == $webCategoryToCheck->id && $triggerWebCategory->pivot->excluded == 0) {
                                        $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
                                        continue 4;
                                    }
                                }

                                foreach ($webCategoryToCheck->webGroups as $webGroupToCheck) {
                                    foreach ($triggerWebGroups as $triggerWebGroup) {
                                        if ($triggerWebGroup->id == $webGroupToCheck->id && $triggerWebGroup->pivot->excluded == 0) {
                                            $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
                                            continue 5;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else {
            foreach ($webCartItems as $webCartItem) {
                $totalPartQuantity = $totalPartQuantity + $webCartItem->quantity;
            }
        }

        return $totalPartQuantity;
    }

    public function setMinimumQuantityAttribute($value) {
        $this->attributes['minimum_quantity'] = $value;
    }

    public function setAnyProductAttribute($value) {
        $this->attributes['any_product'] = $value;
    }

    public function postTriggerOperation($soldToCustomer){}

    /**
     * @param $webProductPaths
     * @param $relevantProducts
     * @param $productType
     * @return bool
     * @deprecated not usable if the pivot table 'excluded' column is needed and check
     */
    private function isValidCartItem($webProductPaths, $relevantProducts, $productType) {
        if ($this->any_product) return true;
        foreach ($webProductPaths as $webProductPath) {
            if ($relevantProducts->contains($webProductPath[$productType])) {
                return true;
            }
        }
        return false;
    }

    public static function boot() {
        parent::boot();

        static::deleted(function (PromotionItemQuantityTrigger $promotionItemQuantityTrigger) {
            $promotionItemQuantityTriggerProducts =
                PromotionItemQuantityTrigger_Product::where('promotionitemquantitytrigger_id', '=', $promotionItemQuantityTrigger->id)->get();
            foreach ($promotionItemQuantityTriggerProducts as $promotionItemQuantityTriggerProduct) {
                $promotionItemQuantityTriggerProduct->delete();
            }
        });
    }
}