/**
 * Made by mkcomponent.sh
 * * Change to Fileheader info *
*/

// Core imports
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'

// Services


@Component({
    moduleId: module.id+ '',
    selector: 'product-configurable',
    templateUrl: './template/t--configurable.pug',
    styleUrls: ['sty.configurable.scss']
})

export class ConfigurableComponent {

    // ---- Variables ---- \\
    @Input('variations') variations: any
    @Output('result') result = new EventEmitter
    attributeMap = new Map
    attributeLabelMap = new Map
    selectedAttribute = new Map
    keys: any = []
    constructor(
    ) {
    }


    // ---- Lifecycle hooks ---- \\
    ngOnInit() {

        // TODO: Make this smarter at some point, for performance
        for(let variant of this.variations) {



            for(let attributes of variant.attributes) {

                if(attributes.code !== 'product_group') {

                    if(!this.attributeMap.has(attributes.code))
                        this.attributeMap.set(attributes.code, [])
                    
                    this.attributeLabelMap.set(attributes.code, attributes.label)
    
                    for(let attribute of Object.keys(attributes)) {
                        let attributeValue = attributes[attribute]
    
                        if(attribute === 'formattedValue') {
                            if(!this.attributeMap.get(attributes.code).includes(attributeValue)) {
                                let attrList = this.attributeMap.get(attributes.code)
                                attrList.push(attributeValue)
                                this.attributeMap.set(attributes.code, attrList)
                            }
                        }
                    }
                }
            }
        }

        this.keys = Array.from(this.attributeMap.keys())
    }
    
    // ---- Functions ---- \\

    /**
     * Updates the `selectedAttribute` Map, then checks if there is an element
     * based on the choices made
     * 
     * @param key 
     * @param value 
     */
    updateAttribute(key, value) {

        this.selectedAttribute.set(key, value.srcElement.value)

        this.getElementBasedOnValues()
    }


    /**
     * Dynamically generates a promise for each attribute found within the `attributeMap`,
     * runs through all promises, and gives a list of variants back that has the given attribute
     * Find the product across all variants that match
     */
    getElementBasedOnValues() {

        let promises = []
        let keys = Array.from(this.attributeMap.keys())

        // Iterates all values and generates a promise for each
        for(let key of keys) {
            promises.push(
                new Promise((resolve) => {
                    let result = this.variations.filter((variant) => {
        
                        return variant.attributes.find(attribute => {
        
                            return attribute.code === key && this.selectedAttribute.get(key) === attribute.formattedValue
                        })
                    })
    
                    resolve(result)
                })
            )
        }

        // Executes all promises defined previously, in succession
        Promise.all(promises).then((response) => {

            var result = response.shift().reduce((res, v) => {
                if (res.indexOf(v) === -1 && response.every((a) => {
                    return a.indexOf(v) !== -1;
                }))

                res.push(v)
                return res
            }, [])

            if(result.length == 1) {
                this.result.emit(result[0])
            }
        })
    }   
}
