import State from "../domain/State";
import Comment from "../domain/Comment";
import Action from "../domain/Action";
import ExplorationEvaluation from "../domain/ExplorationEvaluation";
import BackgroundService from "../domain/BackgroundService";
import Question from "../domain/Question";
import { Step } from "../domain/Step";


export default class FirefoxBackgroundMessageService  implements BackgroundService{

    getState(): Promise<State> {
        return browser.runtime.sendMessage({
                kind: 'getStateForTabScript'
            })
            .then ((data: {
                commentsUp: string[],
                isDisplayingComments: boolean,
                isActive: boolean,
                isRecording: boolean,
                popupCommentPosition: {x: string, y: string},
                webSite: any
            }) => {
                const isActive = data.isRecording ? true : false;
                let commentsUp = []
                if (data.commentsUp && Array.isArray(data.commentsUp)) {
                    commentsUp = data.commentsUp.map((commentText) => Comment.parseComment(commentText));
                }
                const state = new State(
                    commentsUp,
                    data.isDisplayingComments,
                    isActive,
                    data.webSite,
                    data.popupCommentPosition);
                return state;
            });
    }

    getActionList(): Promise<Action[]> {
        return browser.runtime.sendMessage({
                kind: 'getProbabilities'
            })
            .then( data => {
                if (data?.probabilityMap) {
                    const actionList = [];
                    for (const [actionName, probability] of data.probabilityMap) {
                        const action = Action.parseAction(actionName);
                        action.probability = probability;
                        actionList.push(action)
                    }
                    return actionList;
                } else {
                    return [];
                }
            });
    }

    getCommentList(): Promise<Comment[]> {
        return browser.runtime.sendMessage({
                kind: 'getComments'
            })
            .then( data => {
                const comments = []
                if (data?.commentDistributionList) {
                    const commentDistributionList = data.commentDistributionList;
                    for (const commentData of commentDistributionList) {
                        const comment = Comment.parseComment(commentData.note);
                        for (const distribution of commentData.distributions) {
                            comment.addDistribution(distribution.noteOccurence, distribution.contextOccurence, distribution.context.map(actionText => Action.parseAction(actionText)));
                        }
                        comments.push(comment);
                    }
                }
                return comments;
            })
    }

    getExplorationEvaluation(): Promise<ExplorationEvaluation | null> {
        return browser.runtime.sendMessage({
                kind: 'getEvaluation'
            })
            .then((data: {
                validatedStepList: {name: string, expression: string}[];
                notValidatedStepList: {name: string, expression: string}[];
                enteringInteractionList: string[];
                continuingActionList: string[];
                finishingInteractionList: string[];
                questionList: string[];
            }) => {
                return new ExplorationEvaluation(
                    data.validatedStepList.map(stepData => new Step(stepData.name, stepData.expression)),
                    data.notValidatedStepList.map(stepData => new Step(stepData.name, stepData.expression)),
                    data.enteringInteractionList.map(action => Action.parseAction(action)),
                    data.continuingActionList.map(action => Action.parseAction(action)),
                    data.finishingInteractionList.map(action => Action.parseAction(action)),
                    data.questionList.map(text => new Question(text))
                );
            })
    }

    setUserViewPosition(newPosition: {x: number, y:number}): Promise<void> {
        return browser.runtime.sendMessage({
                kind: 'setPopupCommentPosition',
                popupCommentPosition: newPosition
              });
    }

    upComment(comment: Comment): Promise<void> {
        return browser.runtime.sendMessage({
                kind: 'upComment',
                type: comment.type,
                value: comment.note
            });
    }

    sendAction(action: Action): Promise<void> {
        return browser.runtime.sendMessage({
                action,
                kind: 'pushAction'
            }).then((response) => {
                if (!response.error) {
                    return Promise.resolve();
                }
            });
    }

    sendAnswer(question: Question, value: boolean): Promise<void> {
        return browser.runtime.sendMessage({
                question,
                value,
                kind: 'pushAnswer'
            });
    }


}

