/* Copyright CloudLinux Zug GmbH 2010-2017 All Rights Reserved
 *
 * Licensed under CLOUD LINUX LICENSE AGREEMENT
 * http://cloudlinux.com/docs/LICENSE.TXT
 */

import { Injectable } from '@angular/core';
import { AppState } from '../app.service';
import { ViewMode, TitleForViewMode } from '../model/view_mode';
import { Package } from '../model/package';

/**
 * User status for end users.
 * @type {string}
 */
export const US_END_USER: string = 'end-user';

/**
 * User status for reseller.
 * @type {string}
 */
export const US_RESELLER: string = 'reseller';

/**
 * User status for reseller's end users.
 * @type {string}
 */
export const US_RESEND_USER: string = 'resend-user';

/**
 * User status for reseller's end users under admin's limits
 * (reseller's limits is disabled).
 * @type {string}
 */
export const US_RESEND_USER_UNDER_ADMIN: string = 'resend-user-under-admin';

/**
 * Package status for packages created by admin.
 * @type {string}
 */
export const PS_CREATED_BY_ADMIN: string = 'created-by-admin';

/**
 * Package status for packages created by reseller.
 * @type {string}
 */
export const PS_CREATED_BY_RESELLER: string = 'created-by-reseller';

/**
 * Package status for packages created by reseller which have disabled limits.
 * @type {string}
 */
export const PS_CREATED_BY_RESELLER_UNDER_ADMIN: string = 'created-by-reseller-under-admin';

@Injectable()
export class ViewModes {

    /**
     * Available modes for different types of users.
     *
     * @type {ViewMode[]}
     */
    public static availableModes: ViewMode[] = [
        new ViewMode(
            US_END_USER, new TitleForViewMode('End users', 'End user'), true
        ),
        new ViewMode(
            US_RESELLER, new TitleForViewMode('Resellers', 'Reseller'), true
        ),
        new ViewMode(
            US_RESEND_USER, new TitleForViewMode(
                'Reseller\'s end users', 'Reseller\'s end user'
            ), true
        ),
        new ViewMode(
            US_RESEND_USER_UNDER_ADMIN, new TitleForViewMode(
                'Reseller\'s end users (no Reseller limit)',
                'Reseller\'s end user<br>(no Reseller limit)'
            ), true
        )
    ];

    /**
     * Available modes for different types of packages.
     *
     * @type {ViewMode[]}
     */
    public static availableModesForPackages(appState?: any): ViewMode[] {
        return [
            new ViewMode(
                PS_CREATED_BY_ADMIN, new TitleForViewMode('Created by Hoster'), true
            ),
            new ViewMode(
                PS_CREATED_BY_RESELLER, new TitleForViewMode('Created by Reseller'), true
            ),
            new ViewMode(
                PS_CREATED_BY_RESELLER_UNDER_ADMIN, new TitleForViewMode(
                    'Created by Reseller (no Reseller limit)',
                    'Created by Reseller<br>(no Reseller limit)'
                ), true
            )
        ];
    };

    public resellerNames: string[] = [];

    constructor(public appState: AppState) {}

    public removeReseller(excludeResellerName: string) {
        this.resellerNames =
            this.resellerNames.filter(resellerName => resellerName !== excludeResellerName);
    }

    // TODO: Make method static
    public concatResellerWithUser(data) {
        if (!data.resellers)
            return;
        for (let reseller of data.resellers) {
            reseller.username = reseller.name;
            reseller.domain = 'N/A';
            reseller.isReseller = true;
            reseller.resellerStatus = (!!Object.keys(
                reseller.limits || reseller.limit || {}
            ).length);
        }
        data.users = data.users.concat(data.resellers);
    }

    public detectUserTypes(data, curViewModes) {
        let users = data['users'];
        // Todo: limit fields in cloudlinux-top and cloudlinux-utils are different (by spec)
        let resellers = data.hasOwnProperty('resellers') ? data['resellers'].filter(
            reseller => !!Object.keys(reseller.limits || reseller.limit || {}).length
        ) : [];

        for (let reseller of resellers) {
            this.resellerNames.push(reseller['name']);
        }
        for (let user of users) {
            user.userType = US_END_USER;

            if (this.appState.get('listOfAdmins').includes(user.reseller)
                || user.id === 0
            ) {
                user.userType = US_END_USER;
            } else if (user.hasOwnProperty('isReseller') && user.isReseller) {
                user.userType = US_RESELLER;
            } else if (user.hasOwnProperty('reseller')
                && user.hasOwnProperty('username')
            ) {
                user.userType = this.resellerNames.includes(user.reseller)
                    ? US_RESEND_USER
                    : US_RESEND_USER_UNDER_ADMIN;
            }

            user.userTypeTooltip = curViewModes.find((mode) => {
                return mode.name === user.userType;
            }).title.tooltip;
        }
    }

    public detectPackageTypes(data, curViewModes) {
        let packages: Package[] = data['package'];

        for (let pckg of packages) {
            if (this.appState.get('listOfAdmins').includes(pckg.provider)
                || pckg.provider === ''
            ) {
                pckg.packageType = PS_CREATED_BY_ADMIN;
            } else {
                pckg.packageType = pckg.enabledLimits ? PS_CREATED_BY_RESELLER
                    : PS_CREATED_BY_RESELLER_UNDER_ADMIN;
            }
        }
    }

    public switchViewMode(
        availableViewModes: ViewMode[], originalRows, workKey = 'userType'
    ): any[] {
        let rows = [];
        if (this.appState.get('isAdmin')) {
            let checkedModes = availableViewModes
                .filter(mode => mode.checked )
                .reduce((modes, mode) => {
                    return modes.concat(mode.linkedModes);
                }, []);
            rows = originalRows.filter((row, index) => {
                return checkedModes.includes(row[workKey]);
            });
        } else {
            rows = originalRows;
        }
        return rows;
    }

}
