import createReducer from 'lib/reducer';
import backendRequest from 'lib/backend';
import { settingsSelector } from 'utils/settings';

import { fromJS, toJS } from 'immutable';

import moment from 'moment';
import { num } from 'lib/num';

const FORMAT = "YYYY-MM-DD"; //ISO date format
const DEFAULT_PERIOD = "last12Months";

export const PERIODS = {
    last12Months: {
        calcPeriod: () => {
            let m = moment().endOf('month');
            return { 
                to: m.format(FORMAT),
                from: m.subtract('month', 12).add('day', 1).format(FORMAT)
            };
        }
    },
    year: {
        scrollable: true,
        calcPeriod: (val) => {
            let m = moment().add('year', num(val));
            return { 
                year: m.year(),
                to: m.endOf('year').format(FORMAT),
                from: m.startOf('year').format(FORMAT)
            };
        }
    },
    quarter: {
        scrollable: true,
        calcPeriod: (val) => {
            let m = moment().add('quarter', val || 0);
            return { 
                year: m.year(),
                quarter: m.quarter(),
                to: m.endOf('quarter').format(FORMAT),
                from: m.startOf('quarter').format(FORMAT)
            };
        }
    },
    month: {
        scrollable: true,
        calcPeriod: (val) => {
            let m = moment().add('month', val || 0);
            return { 
                year: m.year(),
                month: m.month() + 1,
                to: m.endOf('month').format(FORMAT),
                from: m.startOf('month').format(FORMAT)
            };
        }
    }
};

export const CUSTOM_RANGE_PERIODS = {
    ...PERIODS,

    custom: {
        useRange: true,
        calcPeriod: (val) => {
            if (!val) {
                return PERIODS.last12Months.calcPeriod();
            }
            let boundaries = val.split(";");
            if (boundaries.length != 2) {
                return PERIODS.last12Months.calcPeriod();
            }
            return {
                from: boundaries[0],
                to: boundaries[1]
            }
        }
    }
};


/* */
export const saveParam = (param, value) => {
    //no need to wait for response
    saveParams([{ [param]: value }]);
}

export const saveParams = (params) => {
    //no need to wait for response
    backendRequest("/api/params/user", "PUT", { body: params || [] });
}


/* */
function getPeriodValues(periodType, key, dateType) {
    let period = CUSTOM_RANGE_PERIODS[periodType] || CUSTOM_RANGE_PERIODS[DEFAULT_PERIOD];
    let defaultParams = period.calcPeriod(key);
    
    return  {
        periodType,
        value: key,
        dateType: dateType || "BILLED_DATE",
        ...defaultParams
    };
}

//TODO read data from global config
let { params = {} } = global.cfg;
let defaultPeriods = getPeriodValues(params.periodType || DEFAULT_PERIOD, params.period || 0, params.dateType || "BILLED_DATE");

let initialState = {
    period: defaultPeriods
};

export const selector = (state, props) => {
    let params = state.get("params");
    return params ? params.toJS() : initialState;
};


let reducer = createReducer(initialState);
reducer.handleAction("params/SET_PERIOD", (state, action) => 
    state.setIn(["period"], fromJS(action.payload))
);

export function setPeriod(periodType, period, dateType) {
    //async persist parameter 
    saveParams([{ periodType }, { period }, { dateType }]);
    return {
        type: "params/SET_PERIOD",
        payload: getPeriodValues(periodType, period, dateType)
    };
}


export default reducer.export();