// Core imports
import { Component, HostListener, Inject, PLATFORM_ID } from '@angular/core'
import { isPlatformBrowser } from '@angular/common'
import {
    trigger,
    state,
    style,
    animate,
    transition
} from '@angular/animations'

// Component
import { PriceComponent } from '@k-core/modules/configurator/components/price/cmp.price'

// Global / Shared Services
import { HelperService } from '@k-services/svc.helper'
import { BasketService } from '@k-services/svc.basket'
import { SharedService } from '@k-services/svc.shared'

// Module Services
import { ConfiguratorService }              from '@k-core/modules/configurator/services/svc.configurator'
import { ConfiguratorProductLoaderService } from '@k-core/modules/configurator/services/svc.configurator-product-reloader'
import { StepNavigationService }            from '@k-core/modules/configurator/services/svc.step-navigation'

// Pipes
import { TranslatePipe }    from '@k-core/pipes/pipe.translate'
import { DiscountsService } from '@k-core/common/discount/services/svc.discounts'


// Interfaces
interface FilteredProductAttributes {
    name: string;
    value: string;
} 


/**
 * Extended Price component for IDEmøbler
 */
@Component({
    moduleId: module.id+ '',
    selector: 'configurator-price',
    templateUrl: './tpl.price.pug',
    styleUrls: ['sty.price.scss'],
    animations: [
        // RotateOnActive
        trigger('rotateOnActive', [
            state('active', style({
                transform: 'rotate(-180deg)'
            })),
            state('inactive', style({
                transform: 'rotate(0deg)'
            })),

            transition('active <=> inactive', [
                animate('.2s')
            ])
        ]),

        // Nudge
        trigger('nudge', [
            state('default', 
                style({
                    transform: 'translateY(-{{basket_top_height}}px)'
                }), 
                {params: {basket_top_height: '0'}}
            ),
            state('nudge', 
                style({
                    transform: 'translateY(0)'
                })
            ),

            transition('nudge <=> default', [
                animate('.2s ease-in')
            ])
        ]),

        // Nudge
        trigger('stickToTop', [
            state('default', 
                style({
                    top: '{{headerHeight}}px'
                }), 
                {params: {headerHeight: '0'}}
            ),
            state('stuck', 
                style({
                    top: '0px'
                })
            ),

            transition('stuck <=> default', [
                animate('.2s ease')
            ])
        ])
    ]
})

export class PriceComponent_IDEmobler extends PriceComponent {

    // ---- Variables ---- \\

    // States
    dropdown_active: boolean    = false
    is_last_step: boolean       = false
    nudge_basket: boolean       = false
    is_stuck_to_top: boolean    = false
    override_dropdown: boolean  = false

    // Data
    filtered_product_attributes: FilteredProductAttributes[]


    // Settings
    headerHeight: number        = 65
    basket_top_height: number   = 90
    nudgeBasketOn: string[]     = ['desk-and-up']
    attribute_order: string[]   = ['type_id', 'measurements', 'dessin', 'details']
    default_attribute_value: string = '-'

    
    constructor(
        @Inject(PLATFORM_ID) private platformId: Object,
        helper: HelperService,
        service: ConfiguratorService,
        _preset: ConfiguratorProductLoaderService,
        _basket: BasketService,
        _discount: DiscountsService,
        private _stepNavigation: StepNavigationService,
        private _translate: TranslatePipe,
        private _shared: SharedService
    ) {
        super(helper, service, _preset, _basket, _discount)

        // Check if on last step
        _stepNavigation.currentStep$.subscribe(resp => {
            let steps = _stepNavigation.getSteps()

            if(steps[steps.length - 1].name === resp) {
                this.is_last_step = true

                // reset override
                this.override_dropdown = false
            }
            else {
                this.is_last_step = false
            }
        })

        // Filter product attributes on update
        service.product$.subscribe((resp) => {
            this.filterProductAttributes()
        })

        // Set stuck to top if header is hidden
        _shared.headerVisible$.subscribe((resp) => {
            this.is_stuck_to_top = !resp
        })
    }


    // ---- Lifecycle hooks ---- \\




    // ---- Functions ---- \\

    /**
     * Toggle the state of the dropdown.
     * Will also check for last step and flag override.
     */
    toggleDropdown() {
        this.dropdown_active = !this.dropdown_active
        
        if(this.is_last_step && !this.override_dropdown) {
            this.override_dropdown = true

            // Close overlay even though previous state was closed
            if(this.dropdown_active)
                this.dropdown_active = false
        } 
    }


    getAttributeName(attrName) {

        // console.warn('Getting Attribute...')
        // console.log(attrName)
        // console.log(this.service.specsMap)

        if(this.service.specsMap.has(attrName))
            return this.service.specsMap.get(attrName)
        else
            return attrName
    }


    /**
     * Set boolean value that triggers nudge animation.
     * The function it limited to given breakpoints
     * 
     * @requires `nudgeBasketOn` - controls which breakpoints nudge is active on
     * @requires `basket_top_height` - the value which should be offset on nudge
     */
    nudgeBasket() {
        if(isPlatformBrowser((this.platformId))) {
            let can_be_nudged: boolean = false

            for(let breakpoint of this.nudgeBasketOn) {
                if(this.helper.currentBreakPoint(breakpoint)) {
                    can_be_nudged = true
                }
            }


            if(can_be_nudged) {
                if(document.querySelector('.js-basket')) {
                    let pos = document.querySelector('.js-basket').getBoundingClientRect().top
                    let offset = this.nudge_basket ? this.basket_top_height * 2  : this.basket_top_height


                    if(pos <= 0 + offset) {
                        this.nudge_basket = true
                    }
                    else {
                        this.nudge_basket = false
                    }
                }
            }
            else {
                // Set default value
                this.nudge_basket = false
            }
        }
    }


    /**
     * Filteres products object into a new attributes array with `name` and `value`.
     * If product does not exist or if the attribute has no value a default value is given.
     */
    filterProductAttributes() {
        // reset attributes
        this.filtered_product_attributes = []


        for(let attribute of this.attribute_order) {
            if(!!this.product) {
                let filtered_attribute

                if(this.product[attribute]) {
                    switch(attribute){
                        // Type
                        case 'type_id':
                            filtered_attribute = {
                                name: attribute,
                                value: this.getAttributeName(this.product[attribute]) // Use service to translate
                            }

                            break


                        // Dessin
                        case 'dessin':
                            let dessin = this.product[attribute],
                                color_family = this.product['color-family']

                            filtered_attribute = {
                                name: attribute,
                                value: color_family + ' (' + this.getAttributeName(dessin) + ')'
                            }

                            break

                        case 'details':
                            
                            let detailValues: string = ''
                            let int = 1
                            let addComma = false


                            for(let attr_id of Object.keys(this.product[attribute])) {

                                // Should we add a comma after the string, or is this the last element?
                                if(int < Object.keys(this.product[attribute]).length)
                                    addComma = true

                                detailValues += this._translate.transform(attr_id, 'configurator - basket') + ': ' + (this.getAttributeName(this.product[attribute][attr_id])) + (addComma ? ', ': '')

                                int++
                            }

                            filtered_attribute = {
                                name: attribute,
                                value: detailValues
                            }

                            break

                        // Measurements
                        default:
                            let value: string = '',
                                first: boolean = true,
                                suffix: string =this.product[attribute] === 'measurements' ? 'cm' : ''

                            for(let attr_id of Object.keys(this.product[attribute])) {
                                let separator: string = first ? '' : ', ',
                                    measure = !!this.product[attribute][attr_id] ? this.product[attribute][attr_id] + suffix : this.getAttributeName(this.default_attribute_value)
                                    
                                value += separator + this._translate.transform(attr_id, 'configurator - basket') + ': ' + measure;
                                
                                // Toggle separator value
                                first = false
                            }

                            filtered_attribute = {
                                name: attribute,
                                value: value
                            }
                            break
                    }
                }
                // Default
                else {
                    filtered_attribute = {
                        name: attribute,
                        value: this.default_attribute_value
                    }
                }


                this.filtered_product_attributes.push(filtered_attribute)
            }
            // Set default values for attributes if product is not available
            else {
                this.filtered_product_attributes.push({
                    name: attribute,
                    value: this.default_attribute_value
                })
            }
        }
    }





    // ---- Listeners ---- \\

    /**
	 * Listen to window scroll
	 */
	@HostListener('document:scroll', ['$event'])
	onWindowScroll() {
        this.nudgeBasket()
        
        if(!this.basketWidth)
            this.setWidth()
    }
}
