import Question from "../../background/domain/Question";
import ActionProbabilityMap from "./ActionProbabilityMap";
import BackgroundService from "./BackgroundService";
import Comment from "./Comment";
import EventListener from "./EventListener";
import ExplorationEvaluation from "./ExplorationEvaluation";
import PageMutationHandler from "./PageMutationHandler";
import RuleService from "./RuleService";
import State from "./State";
import StyleManager from "./StyleManager";
import ViewManagerService from "./ViewManagerService";

export default class TabScript {

    private _backgroundService : BackgroundService;
    private _shadowMode : boolean;
    private _ruleService : RuleService;
    private _eventListener : EventListener;
    private _styleManager : StyleManager;
    private _pageMutationHandler : PageMutationHandler;
    

    constructor(backgroundService : BackgroundService, shadowMode : boolean = false) {
        this._backgroundService = backgroundService;
        this._shadowMode = shadowMode
        this._ruleService = new RuleService();

        this._eventListener = new EventListener(this._ruleService, this._backgroundService);
        this._eventListener.addActionPushedToBackgroundListener(this.onActionPushedToBackground.bind(this));
        this._styleManager = new StyleManager();
        
        this._pageMutationHandler = new PageMutationHandler(this.onMutation.bind(this));
        this._pageMutationHandler.init();
        
    }

    synchronizeWithBackground() : Promise<void> {
        return this._backgroundService.getState()
            .then(state => {
                let rules = state.webSite.mappingList.map(ru => this._ruleService.createRule(ru));
                this._ruleService.loadRules(rules);
                this._ruleService.attachRulesToElements();
                if (state.isActive) {
                    this.explorationStarted();
                }
            })
    }

    linkToViewManager(viewManager : ViewManagerService) {
        this._styleManager.linkToViewManager(viewManager);
    }

    getState() : Promise<State> {
        return this._backgroundService.getState();
    }

    getCommentList(): Promise<Comment[]> {
        return this._backgroundService.getCommentList();
    }

    getProbabilityMap(): Promise<ActionProbabilityMap> {
        return this._backgroundService.getProbabilityMap();
    }

    getRuleService() : RuleService {
        return this._ruleService;
    }

    getExplorationEvaluation(): Promise<ExplorationEvaluation | null> {
        return this._backgroundService.getExplorationEvaluation();
    }

    explorationStarted() : Promise<void> {
        this._eventListener.explorationStarted();
        if (!this._shadowMode) {
            return this._styleManager.explorationStarted()
        } else {
            return Promise.resolve();
        }
        
    }

    explorationStopped() : void {
        this._eventListener.explorationStopped();
        if (!this._shadowMode) {
            this._styleManager.explorationStopped();
        } 
    }

    reload() : Promise<void> {
        return this._backgroundService.getState()
            .then(state => {
                let rules = state.webSite.mappingList.map(ru => this._ruleService.createRule(ru));
                this._ruleService.loadRules(rules);
            })
    }

    commentConfirmed(comment: Comment) {
        return this._backgroundService.upComment(comment);
    }

    setUserViewPosition(newPosition : {x : number, y: number}) {
        this._backgroundService.setUserViewPosition(newPosition);
    }

    pushAnswer(question: Question, value: boolean) {
        this._backgroundService.sendAnswer(question, value);
    }

    private onMutation() {
        this._ruleService.attachRulesToElements();
        if (!this._shadowMode) {
            this._styleManager.refresh();
        }
        
    }

    private onActionPushedToBackground() {
        if (!this._shadowMode) {
            this._styleManager.refresh();
        }
    }

}