import _ from "lodash";
import wait_for_computation_async from "../async_calls"

export default {
    state: {
        pregraftData: null,
        graftingStarted: false
    },
    getters: {
        getPregraftData(state) {
            return state.pregraftData;
        },
        getGraftingStarted(state, getters) {
            return state.graftingStarted
        }
    },
    mutations: {
        setPregraftData(state, data) {
            state.pregraftData = data;
        },
        setGraftingStarted(state, started) {
            state.graftingStarted = started;
        },
        removeGrafts(state) {
            state.grafts = [];
        }
    },
    actions: {

        pregraft(context) {
            let request = context.getters.getApi.post("/pregraft/submit", {
                scaffold: {
                    pdb: context.getters.getScaffold.name,
                    chain: context.getters.getScaffold.chain
                },
                insert: {
                    pdb: context.getters.getInsert.name,
                    chain: context.getters.getInsert.chain,
                },
                loop_pairing: context.getters.getWantedLoops.map(l => (
                    {
                        candidate: {
                            name: l.id,
                            ss1_start: l.start,
                            ss1_end: l.coilStart,
                            ss2_start: l.coilEnd,
                            ss2_end: l.end
                        },
                        replacement: {
                            name: l.replacement.id,
                            ss1_start: l.replacement.start,
                            ss1_end: l.replacement.coilStart,
                            ss2_start: l.replacement.coilEnd,
                            ss2_end: l.replacement.end

                        }
                    }
                ))
            }).then((response) => {
                return wait_for_computation_async(context.getters.getApi, "pregraft", 10000, response.data.taskId)
            }).then((response) => {
                if (!response.data.canBeRetrieved) {
                    throw new Error("Computation of pregrafting data has failed.")
                }
                return context.getters.getApi.get(`/pregraft/${response.data.taskId}/results`);
            }).then((response) => {
                context.commit("setPregraftData", {
                    sequences: Object.values(response.data.sequences),
                });
            }).catch(err => {
                context.dispatch("setErrorMessage", { error: err });
                throw err;
            });

            context.dispatch("addAwaitable", {
                id: _.uniqueId("awaiting"),
                promise: request,
                description: `Pregrafting...`
            });
        },
        startGrafting(context, { rosseta, modeller }) {
            let request = context.getters.getApi.post("/graft/submit", {
                licences: {
                    rosseta: rosseta,
                    modeller: modeller
                },
                scaffold: {
                    pdb: context.getters.getScaffold.name,
                    chain: context.getters.getScaffold.chain
                },
                insert: {
                    pdb: context.getters.getInsert.name,
                    chain: context.getters.getInsert.chain,
                },
                loop_pairing: context.getters.getWantedLoops.map(l => (
                    {
                        candidate: {
                            name: l.id,
                            ss1_start: l.start,
                            ss1_end: l.coilStart,
                            ss2_start: l.coilEnd,
                            ss2_end: l.end
                        },
                        replacement: {
                            name: l.replacement.id,
                            ss1_start: l.replacement.start,
                            ss1_end: l.replacement.coilStart,
                            ss2_start: l.replacement.coilEnd,
                            ss2_end: l.replacement.end

                        }
                    }
                ))
            }).then(() => {
                context.commit("setGraftingStarted", true);
            }).catch(err => {
                context.dispatch("setErrorMessage", { error: err });
                throw err;
            });

            context.dispatch("addAwaitable", {
                id: _.uniqueId("awaiting"),
                promise: request,
                description: `Grafting...`
            });
        },


    }
}