import { Component, Input } from '@angular/core';
import { ObservableArray } from '@nativescript/core';
import { EnrollNumberAllUsageOutput } from '~/pages/sts/entities/output/enrollNumberAllUsageOutput';
import { StsDetailStatsChartSource } from '~/pages/sts/entities/sts-detail-stats-chart-source';

@Component({
    selector: 'StsDetailStatsChart',
    moduleId: module.id,
    templateUrl: './sts-detail-stats-chart.component.html',
    styleUrls: ['./_sts-detail-stats-chart.component.scss']
})
export class StsDetailStatsChartComponent {
    callsObservable: any;
    messagesObservable: any;
    dataObservable: any;
    callsObservableKeys: string[];
    messagesObservableKeys: string[];
    dataObservableKeys: string[];
    typeToDisplayName = {
        data: 'Datové přenosy',
        sms: 'SMS v síti T-Mobile',
        smsout: 'SMS mimo síť T-Mobile',
        call: 'Volání v síti T-Mobile',
        callsts: 'Volání v STS (zdarma)',
        callout: 'Volání mimo síť T-Mobile'
    };

    /**
     * It prepare data for graph. Which need data in ObservableArray type
     * There is object where key is ID_CallServiceType and value is array of StsDetailStatsChartSource
     *
     * @param {EnrollNumberAllUsageOutput[]} value
     */
    @Input() set enrollNumberUsages(value: EnrollNumberAllUsageOutput[]) {
        const calls = value.reduce((acc: any, curr) => {
            if (curr.ID_CallServiceType && (Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 3 ||
            Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 4 ||
            Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 5)) {
                this.fillStatDataAcc(acc, curr);
            }

            return acc;
        }, {});

        const messages = value.reduce((acc: any, curr) => {
            if (curr.ID_CallServiceType && (Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 1 ||
                Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 2)) {
                this.fillStatDataAcc(acc, curr);
            }

            return acc;
        }, {});

        const data = value.reduce((acc: any, curr) => {
            if (curr.ID_CallServiceType && Object.keys(this.typeToDisplayName).indexOf(curr.ID_CallServiceType) === 0) {
                this.fillStatDataAcc(acc, curr);
            }

            return acc;
        }, {});

        // const callsKeys = Object.keys(calls);
        this.callsObservable = Object.keys(calls).reduce((acc, curr) => ({
            ...acc,
            [curr]: new ObservableArray(calls[curr])
        }), {});
        this.callsObservableKeys = Object.keys(this.callsObservable);

        this.messagesObservable = Object.keys(messages).reduce((acc, curr) => ({
            ...acc,
            [curr]: new ObservableArray(messages[curr])
        }), {});
        this.messagesObservableKeys = Object.keys(this.messagesObservable);

        this.dataObservable = Object.keys(data).reduce((acc, curr) => ({
            ...acc,
            [curr]: new ObservableArray(data[curr])
        }), {});
        this.dataObservableKeys = Object.keys(this.dataObservable);
    }

    /**
     * This is function for reduce operator.
     * It create new property in object or add data to existing property according to if ID_CallServiceType exist in object keys
     *
     * @param acc
     * @param curr
     */
    private fillStatDataAcc(acc: any, curr) {
        if (acc.hasOwnProperty(curr.ID_CallServiceType)) {
            acc[curr.ID_CallServiceType].push(
                new StsDetailStatsChartSource(
                    curr.ID_CallServiceType,
                    `${curr.Month}/${curr.Year}`,
                    this.transformQuantity(curr.Quantity, curr.ID_CallServiceType)
                )
            );
        } else {
            acc[curr.ID_CallServiceType] = [
                new StsDetailStatsChartSource(
                    curr.ID_CallServiceType,
                    `${curr.Month}/${curr.Year}`,
                    this.transformQuantity(curr.Quantity, curr.ID_CallServiceType)
                )
            ];
        }
    }

    /**
     * It transform quantity for better display in graph
     * If type of data are internet 'data' then return quantity / 100, otherwise return quantity
     *
     * @param {number} quantity
     * @param {string} type
     * @returns {number}
     */
    private transformQuantity(quantity: number, type: string): number {
        return quantity;
    }
}
