/**
 * Хранилище данных о доменах организации
 */

import _ from 'lodash';
import Immutable from 'immutable';
import { ReduceStore } from 'flux/utils';
import { DomainConfirmationServices } from 'constants/Domain';
import { ActionTypes } from 'constants/Common';
import dispatcher from 'dispatcher';

function normalize(domain) {
    if (!domain) {
        return null;
    }

    try {
        return decodeURIComponent(domain);
    } catch (e) {
        // empty
    }
}

class DomainConfirmationStore extends ReduceStore {
    getInitialState() {
        return new Immutable.Map();
    }

    reduce(state, action) {
        const { data, type } = action;

        switch (type) {
            case ActionTypes.RECEIVE_MIXED_DATA:
                return this._receiveMixedData(state, data);
        }

        return state;
    }

    _receiveMixedData(state, data) {
        if (data && data.confirmation && data.confirmation.domain) {
            return state.set(data.confirmation.domain, Immutable.Map(data.confirmation));
        }

        return state;
    }

    /**
     * Возвращает значение по ключу из состояния хранилища
     * @method  get
     * @param   {String}  key
     * @returns {String}
     */
    get(key) {
        return this.getState().get(key);
    }

    getIn(keys) {
        return this.getState().getIn(keys);
    }

    isOccupied(domain) {
        return this.getIn([normalize(domain), 'isOccupied']);
    }

    /**
     * Возвращает список методов для подтверждения домена
     * @param {String} domain
     * @returns {Array}
     */
    getMethods(domain) {
        const methods = this.getState().getIn([normalize(domain), 'methods']) || [];

        return _.sortBy(methods, 'weight')
            // пока не работает подтверждение через делегирование, так что вырезаем его
            .filter(item => item.method !== 'webmaster.dns_delegation');
    }

    /**
     * Возвращает список методов для подтверждения домена
     * @param {String} domain
     * @returns {undefined|String}
     */
    getConfirmationMethod(domain) {
        const lastCheckInfo = this.getLastCheckInfo(domain);

        return lastCheckInfo && lastCheckInfo.method;
    }

    /**
     * Возвращает объект с данными о последней проверке
     * @param {String} domain
     * @returns {undefined|Object}
     */
    getLastCheckInfo(domain) {
        return this.getState().getIn([normalize(domain), 'last_check']);
    }

    getStatus(domain) {
        return this.getState().getIn([normalize(domain), 'status']);
    }

    /**
     * Возвращает название сервиса через который нужно подтвердить домен
     * @param {String} domain
     * @returns {String}
     */
    getConfirmationService(domain) {
        const methods = this.getMethods(domain) || [];
        const serviceName = _.get(methods[0], 'method', '').split('.')[0];
        const isServiceAvailable = Object.keys(DomainConfirmationServices)
            .reduce((result, service) => result || DomainConfirmationServices[service] === serviceName, false);

        return isServiceAvailable ? serviceName : DomainConfirmationServices.PDD;
    }

    /**
     * Показывает выполняется ли проверка владения доменом в данный момент
     * @param {String} domain
     * @returns {Boolean}
     */
    isCheckInProgress(domain) {
        return this.getState().getIn([normalize(domain), 'status']) === 'in-progress';
    }
}

export default window.ya.connect.DomainConfirmationStore = new DomainConfirmationStore(dispatcher);
