import { fromJS } from 'immutable';

import createReducer from 'lib/reducer';
import backendRequest from 'lib/backend';

import { appLocales } from '../../config.js';



const reduxKey = "@initSettings";

//basic initial state
export const initialState = fromJS({
    pending: true,
    data: global.cfg.unit || {},
    step: 0
});

const unitId = global.cfg.unitId;


const reducer = createReducer(initialState);


export function fetchProfilesAction() {
    return {
        type: reduxKey + "/FETCH_PROFILES",
        payload: backendRequest(`/api/profiles`, 'GET')
    };
}

reducer.handleAction(reduxKey + '/FETCH_PROFILES_PENDING', (state, action) => { 
    return state.set("pending", true);
});

reducer.handleAction(reduxKey + '/FETCH_PROFILES_FULFILLED', (state, action) => { 
    
    let locale = state.getIn(["data", "locale"]);
    let selectedProfile = state.getIn(["data", "profile"]);

    let response = action.payload;
    let profiles = [];
    if (response.body) {
        profiles = response.body;
    }

    if (!Array.isArray(profiles)) {
        profiles = [];
    }

    let countries = [];
    let countriesSet = {};
    let profilesMap = {};
    let states = {};
    let p = null;
    let defaultProfile = null;

    for (let i = 0; i < profiles.length; i++) {
        p = profiles[i];
        if (!countriesSet[p.country]) {
            countriesSet[p.country] = true;
            countries.push(p);
        }

        if (p.state) {
            let sts = states[p.country];
            if (!sts) {
                sts = [];
            }
            sts.push(p);
            states[p.country] = sts;
        }
        
        if (!selectedProfile && p.language == locale && !defaultProfile) {
            selectedProfile = p.id;
            defaultProfile = p;
        }

        profilesMap[p.id] = p;
    }
    Object.keys(states).forEach(key => {
        let s = states[key];
        s.sort(function(a, b){
            return a.stateName < b.stateName ? -1 : 1;
        });
    });
    countries.sort((a, b) => {
        if (a == defaultProfile) {
            return -10000;
        } else if (b == defaultProfile) {
            return 10000;
        }
        return a.countryName < b.countryName ? -1 : 1;
    });


    state = state.set("pending", false).set("profiles", profilesMap).set("countries", countries).set("states", states).setIn(["data", "profile"], selectedProfile);

    if (defaultProfile) {
        state = mergeData(state, readProfile(defaultProfile, states));
    }

    return state;
});

reducer.handleAction(reduxKey + '/FETCH_PROFILES_REJECTED', (state, action) => { 
    return state.set("pending", false).set("error", fromJS(action.payload));
});


export function previousStep() {
    return {
        type: reduxKey + "/PREVIOUS_STEP"
    };
}

reducer.handleAction(reduxKey + '/PREVIOUS_STEP', (state, action) => { 
    let step = state.get("step");
    if (step > 0) {
        step--;
    }
    return state.set("step", step);
});


export function submitProfiles(payload) {
    return {
        type: reduxKey + "/SUBMIT_PROFILES",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_PROFILES', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    let profile = state.get("profiles")[payload.profile];
    let states = state.get("states");

    state = mergeData(state, readProfile(profile, states, payload.state));
    state = state.set("step", step).setIn(["data", "profile"], payload.profile).setIn(["data", "state"], payload.state);

    return state;
});

export function profileSelector(state) {
    return selector(state);
}


export function submitLocalSettings(payload) {
    return {
        type: reduxKey + "/SUBMIT_LOCAL_SETTINGS",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_LOCAL_SETTINGS', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    state = mergeData(state, payload);
    state = state.set("step", step);

    return state;
});

export function submitTaxes(payload) {
    return {
        type: reduxKey + "/SUBMIT_TAX",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_TAX', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    state = mergeData(state, payload);
    state = state.set("step", step);

    return state;
});

export function submitCompany(payload) {
    return {
        type: reduxKey + "/SUBMIT_COMPANY",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_COMPANY', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    let data = state.get("data").toJS();
    if (!data.emailSignature) {
        if (payload.address) { 
            data = { emailSignature: data.name + "\n\n" + data.address, ...payload };
        } else {
            data = { emailSignature: data.name, ...payload };
        }
    } else {
        data = payload;
    }

    state = mergeData(state, data);
    state = state.set("step", step);

    return state;
});

export function submitPaymentMethod(payload) {
    return {
        type: reduxKey + "/SUBMIT_PAYMENT_METHOD",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_PAYMENT_METHOD', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    state = mergeData(state, payload);
    state = state.set("step", step);

    return state;
});

export function submitInvoice(payload) {
    return {
        type: reduxKey + "/SUBMIT_INVOICE",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_INVOICE', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    state = mergeData(state, payload);
    state = state.set("step", step);

    return state;
});

export function submitPersonal(payload) {
    return {
        type: reduxKey + "/SUBMIT_PERSONAL",
        payload
    };
}

reducer.handleAction(reduxKey + '/SUBMIT_PERSONAL', (state, { payload }) => { 
    let step = state.get("step");
    step++;

    state = mergeData(state, payload);
    state = state.set("step", step);

    return state;
});


export function updateSettings(payload) {
    return {
        type: reduxKey + "/UPDATE_SETTINGS",
        payload
    };
}

reducer.handleAction(reduxKey + '/UPDATE_SETTINGS', (state, { payload }) => { 
    return mergeData(state, payload);
});


export function saveAction(data) {
    return {
        type: reduxKey + "/SAVE",
        payload: backendRequest(`/api/${data.id}/unit/${data.id}`, "PUT", { body: data })
    }
}

reducer.handleAction(reduxKey + '/SAVE_PENDING', (state, action) => { 
    return state.set("pending", true);
});

reducer.handleAction(reduxKey + '/SAVE_FULFILLED', (state, action) => { 
    return state.set("pending", false);
});

reducer.handleAction(reduxKey + '/SAVE_REJECTED', (state, action) => { 
    return state.set("pending", false);
});

export const selector = (state) => {
    return state.get("initSettings").toJS();
};

export default reducer.export();



function mergeData(state, vals) {
    let data = state.get("data").toJS();
    data = { ...data, ...vals };
    return state.set("data", fromJS(data));
}


function readProfile(profile, states, selectedState) {
    let vals = {};
    if (profile) {
        let locale = profile.language || "en";

        let loc = "en";
        for (let i = 0; i < appLocales.length; i++) {
            if (appLocales[i] == locale) {
                loc = locale;
                break;
            }
        }

        vals = { locale: loc, language: loc, profile: profile.id, state: null };

        let sts = states[profile.country];
        if (sts && sts.length) {
            if (selectedState) {
                for (let i = 0; i < sts.length; i++) {
                    let state = sts[i];
                    if (state.id == selectedState) {
                        vals.taxTemplates = state.taxTemplates.slice();
                        vals.timezone = state.timezone;
                        break;
                    }
                }

            } else {
                vals.taxTemplates = [];
                vals.timezone = null;
            }

        } else {
            vals.taxTemplates = profile.taxTemplates.slice();    
            vals.timezone = profile.timezone;
        }

        vals.currency = profile.currency;
        vals.currencySymbol = profile.currencySymbol;
        vals.currencyFormat = profile.currencyFormat;
        
        vals.decimalDelimiter = profile.decimalDelimiter;
        vals.thousandDelimiter = profile.thousandDelimiter;
        vals.dateFormat = profile.dateFormat;

        vals.invoiceEmailSubject = profile.invoiceEmailSubject;
        vals.emailSignature = profile.emailSignature;
        vals.invoiceThankYouNote = profile.invoiceThankYouNote;
    }

    return vals;
}