import ActionProbabilityMap from "../domain/ActionProbabilityMap";
import State from "../domain/State";
import BackgroundMessageService from "./BackgroundMessageService";
import PageMutationHandler from "../_ui/PageMutationHandler";
import Comment from "../domain/Comment";
import ActionBorderView from "../_ui/ActionBorderView";
import ActionsPopupView from "../_ui/ActionsPopupView";
import CommentPopupView from "../_ui/CommentPopupView";
//import ObjectiveView from "../_ui/ObjectiveView";

import RuleService from "../domain/rules/RuleService";
import Action from "../../background/domain/Action";

const REFRESH_INTERVAL = 8000;

export default class StyleApplication {

    backgroundMessageService: BackgroundMessageService;
    mutationController: PageMutationHandler;
    actionDisplay: ActionBorderView;
    actionPopup: ActionsPopupView;
    commentPopup: CommentPopupView;
    //objectiveView: ObjectiveView;

    state: State;
    ruleService: RuleService

    constructor(state: State, ruleService: RuleService, backgroundMessageService: BackgroundMessageService) {
        this.state = state;
        this.ruleService = ruleService;
        this.actionDisplay = new ActionBorderView();
        this.actionPopup = new ActionsPopupView(this.onMouseHoverAction.bind(this));
        this.commentPopup = new CommentPopupView(this.onCommentPopupMove.bind(this), this.onCommentUp.bind(this));
        this.backgroundMessageService = backgroundMessageService;
        this.mutationController = new PageMutationHandler(this.onPageMutation.bind(this));
    }

    init(): Promise<void> {
        return Promise.all([
                this.mutationController.init(),
                this.actionPopup.init(),
                this.actionDisplay.init(this.state, this.ruleService),
                this.commentPopup.init(this.state.popupCommentPosition)
            ]).then(() => {
                setInterval(() => {
                    this.refresh()
                }, REFRESH_INTERVAL);
                return this.refresh();
            })
    }

    show(): Promise<void> {
        if (! this.state.isActive) {
            return Promise.resolve();
        }
        return Promise.all([
            this.actionDisplay.show(),
            this.actionPopup.attach(this.state),
            this.commentPopup.show(this.state)
        ])
        .then(() => { return })
    }

    hide(): Promise<void> {
        return Promise.all([
            this.actionDisplay.hide(),
            this.actionPopup.hide(),
            this.commentPopup.hide()
        ])
        .then(() => { return })
    }

    refresh(): Promise<void> {
        return this.backgroundMessageService.getState()
            .then((state) => {
                this.state = state;
                if (!this.state.isActive) {
                    return Promise.resolve();
                }
                const refreshActionsPromise = this.backgroundMessageService.getProbabilityMap()
                    .then((probabilityMap: ActionProbabilityMap) => {
                        this.state.elementActionListMap = probabilityMap.getActionsForElement(this.ruleService);    
                        return Promise.all([
                            this.actionDisplay.refresh(this.state, this.ruleService),
                            this.actionPopup.refresh(this.state),
                        ]);
                })
                const refreshCommentsPromise = this.backgroundMessageService.getCommentList()
                    .then((commentList: Comment[]) => {
                        this.state.commentList = commentList
                        return this.commentPopup.refresh(this.state);
                })
                return Promise.all([
                    refreshActionsPromise, 
                    refreshCommentsPromise
                ])
            .then(() => {return})
        })
            
    }

    onExplorationStopped(): Promise<void> {
        this.state.isActive = false;
        return this.hide();
    }
    onExplorationStarted(): Promise<void> {
        this.state.isActive = true;
        return this.show();
    }

    onActionPushed(action: Action): Promise<void> {
        return this.refresh()
    }

    onReload(): Promise<void>{
        return this.backgroundMessageService.getState()
            .then(state => {
                this.state = state;
                this.ruleService.loadRules(this.state.webSite);
        }).then(() => {
            return this.refresh()
        })
    }

    onPageMutation(): Promise<void> {
        return this.refresh();
    }

    onCommentPopupMove(newPosition): Promise<void> {
        return this.backgroundMessageService.setCommentPopupPosition(newPosition);
    }

    onCommentUp(comment: Comment): Promise<void> {
        return this.backgroundMessageService.upComment(comment);
    }

    onMouseHoverAction(): Promise<void> {
        if (this.state.isActive) {
            return this.actionPopup.refresh(this.state).then(() => {
                this.actionPopup.show();
            })
        }
        return Promise.resolve()
    }

}
