
// Core imports
import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core'
import { isPlatformBrowser } from '@angular/common'
import { HttpClient } from '@angular/common/http'

// Material
import {MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'
import { Overlay } from '@angular/cdk/overlay'

// Settings
import { apikey, server, websiteId, storeId, storeCode } from '@k-settings/store-helper'

// Services
import { CookieService } from 'ng2-cookies'

import { store, website } from '@k-settings/app-setup'
import { GoogleApisService } from '@k-core/services/svc.googleApis'
import { map, tap } from 'rxjs/operators'
import { Observable } from 'rxjs'
import { HelperService } from '@k-core/services/svc.helper'
import { forkJoin } from 'rxjs/observable/forkJoin'
import { response } from 'express'
import { from } from 'rxjs/observable/from'
import { of } from 'rxjs/observable/of'
import { ActiveCartService } from '@k-core/services/active-cart.service'


interface Campaign {
    content: string;
    cta: {
        text: string;
        link: string;
    }
    colors: {
        foreground: string;
        background: string;
    }
}

interface BusCampaign {
    aktiv: string
    scope: string
    site: string
    slutdato: string
    startdato: string
    tekst: string
}


/**
 * @name CampaignDialogParentComponent
 * @description *watdo?*
 * @author Charles Gouldmann - Klean
 * @since Mon Jul 15 2019
 * @extends
 */
@Component({
    moduleId: module.id+ '',
    selector: 'campaign-dialog',
    template: '',
    styles: [':host {padding: 0;}']
})

export class CampaignDialogComponent implements OnInit {

    // ---- Variables ---- \\
    // Data
    campaign: Campaign
    busCampaign: {current: BusCampaign[], archive: BusCampaign[]}

    constructor(
        @Inject(PLATFORM_ID) private _platformId,
        private helper: HelperService,
        private _http: HttpClient,
        private _cookie: CookieService,
        private _dialog: MatDialog,
        private overlay: Overlay,
        private googleApis: GoogleApisService,
        private activeCart: ActiveCartService
    ) { }


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

        // Init if is Browser and cookie does not exist and not on bus scope
        if(isPlatformBrowser(this._platformId) && store !== 'bus') {
            if(!this.hasCookie()) {
                this.getCampaigns()
            }
        }


        if(isPlatformBrowser(this._platformId) && store === 'bus') {

            this.activeCart.getActiveCartLink()

            this.activeCart.activeCartLink$.subscribe((response) => {

                this._dialog.closeAll()

                this.renderDialog(response)
            })

        }
    }
    

    

    renderDialog(activeCartLink) {

        forkJoin(this.googleApis.getSheet('2PACX-1vSynFbb6ulqiA7OSZqCBkvSGupq4D2P8Zswi8PTpQP4wry8xGRB-t4agQ1vQ0hQDjmcR8Uy8_MJrpHv'), of(activeCartLink))
            .pipe(

                // Remove inactive discounts
                map((response: [BusCampaign[], any]) => [response[0].filter((campaign: any) => campaign.aktiv.toLowerCase() === 'yes' || campaign.aktiv.toLowerCase() === 'ja'), response[1]] ),

                // Remove discounts that don't apply to the current scope... slightly iffy
                map((response: [BusCampaign[], any]) => {

                    const scopeCodes = response[0].filter((campaign) => website.toLowerCase().includes(campaign.site.toLowerCase()))

                    if(!scopeCodes.length) {
                        this.getCampaigns()
                        throw 'no scopes found'
                    } else {
                        this.campaign = undefined // unsets campaign if busCampaign is true
                    }

                    return [scopeCodes, response[1]] 
                }),

                // Sort element by dates, before returning it
                map((response: [BusCampaign[], any]) => this.sortByDate(response))
            )

            .subscribe((response: {current: BusCampaign[], archive: BusCampaign[]}) => {

                // Checks if there's any values in either returned array
                if(Object.values(response).some((campaign) => campaign.length)) {
                    this.busCampaign = response
                    this.openDialog(BusCampignDialogComponent, response)
                }
            })
    }


    /**
     * Finds the active, and previously active Campaigns, and sorts them into `campaignContainer` based on their current state
     * 
     * @param campaigns 
     * @returns 
     */
    private sortByDate(campaigns: [BusCampaign[], any]): {current: BusCampaign[], archive: BusCampaign[]} {

        // Changes date order from DD:MM:YYYY to MM:DD:YYYY
        const d = (date): number => {
            // Regex catches all none-nummeric symbols and splits on them, so it doesn't matter if ., - or / are used
            date = date.split(/(?![0-9])\D/g)
            return new Date(`${date[1]}/${date[0]}/${date[2]}`).getTime()
        }
        
        const currentDate: number = new Date().getTime()
        const orderDate: number = new Date(campaigns[1].created_at).getTime()


        const campaignContainer: {current: BusCampaign[], archive: BusCampaign[]} = {
            current: [],
            archive: []
        }

        // Iterate all campaigns within the response, and group them based on their state
        for(let campaign of campaigns[0]) {

            if(d(campaign.startdato) < currentDate && (d(campaign.slutdato) + 86400000) > currentDate) {
                campaignContainer.current.push(campaign)
            }

            if(d(campaign.startdato) < orderDate && (d(campaign.slutdato) + 86400000) > orderDate && campaigns[1]) {
                campaignContainer.archive.push(campaign)
            }
        }

        return campaignContainer
    }


    /**
     * Gets the campaigns as observable, and returns the data.campaign rules
     * @returns 
     */
    private requestCampaigns(): Observable<any> {
        const data = {
			key: apikey,
			websiteId: websiteId,
            storeId: storeId,
            noCache: true
        }
        
        return this._http.post(server + '/feed/get/active-cart-rules', data)
            .pipe(map((response: any) => {

                if(response.status === 'success') {
                    return response.data.campaign
                }

                // Throw will never trigger as long as status is success
                throw response.data.errorMessage
            }))
    }


    /**
     * Draw the campaign dialog
     */
    private getCampaigns() {

        this.requestCampaigns().subscribe((campaignData) => {

            // Set data on success
            if(campaignData) {
                this.campaign = campaignData

                setTimeout(() => {
                    this.openDialog(CampaignDialogContentComponent, campaignData)
                }, 1000)
            }
        })
    }


    /**
     * Opens the dialog
     * 
     * @param component 
     * @param data 
     */
    private openDialog(component, data: any) {

        const isBusCampaign = component == BusCampignDialogComponent &&  new Set(['segadk', 'gardinbuscom', 'kirsch', 'nyegardinerdk']).has(storeCode.split('_')[0])

        this._dialog.open(component, {
            panelClass: ['mat-dialog', 'mod--no-bg', isBusCampaign ? 'bus-campaign' : 'regular-campaign'],
            hasBackdrop: false,
            closeOnNavigation: true,
            scrollStrategy: this.overlay.scrollStrategies.reposition(),
            position: {
                bottom: "20px",
                right: '20px'
            },
            data: data
        })
    }


    /**
     * Checks for cookie
     */
    public hasCookie() {
        let hasCookie = false

        if(this._cookie.get('campaign-dialog')) {
            hasCookie = true
        }

        return hasCookie
    }
}







/**
 * @name CampaignDialogComponent
 * @description *watdo?*
 * @author Charles Gouldmann - Klean
 * @since Mon Jul 15 2019
 * @extends
 */
@Component({
    moduleId: module.id+ '',
    selector: 'campaign-dialog-content',
    templateUrl: './template/t--campaign-dialog.pug',
    styleUrls: ['sty.campaign-dialog.scss']
})

export class CampaignDialogContentComponent {

    // ---- Variables ---- \\
    // Data
    campaign: Campaign


    constructor(
        private _dialogReference: MatDialogRef<CampaignDialogComponent>,
        private _cookie: CookieService,
        @Inject(MAT_DIALOG_DATA) public data: any
    ) { }





    // ---- Lifecycle hooks ---- \\
    ngOnInit() {
        if(!!this.data) {
            this.campaign = this.data
        }
    }





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

    /**
     * Close dialog
     * 
     * @requires setCookie()
     */
    closeDialog() {
        this._dialogReference.close()
        this.setCookie()
    }


    /**
     * Will set a cookie that expires in 1 day
     */
    setCookie() {
        let tomorrow = new Date()
        tomorrow.setDate(tomorrow.getDate() + 1)

        this._cookie.set('campaign-dialog', 'dismissed', tomorrow)
    }
}


@Component({
    moduleId: module.id+'',
    templateUrl: './template/bus-campaign-content.template.pug',
    styleUrls: ['./bus-campaign.content.style.scss']
})
export class BusCampignDialogComponent {

    public closed: boolean = true

    constructor(
        @Inject(MAT_DIALOG_DATA) public data: any
    ) {
    }
}