import BrowserService from "./BrowserService";
import Tab from "./Tab";
import Window from "./Window";

export default class AifexPopup {

    private _browserService: BrowserService;
    private _aifexWindow: Window;
    private _aifexTab: Tab;

    get isDetached():boolean {
        return this._aifexTab !== undefined;
    }

    constructor(browserService: BrowserService) {
        this._browserService = browserService;
        this._aifexWindow = undefined;
        this._aifexTab = undefined;
    }

    get aifexPageUrl(): string {
        return this._browserService.aifexPopupActivatedUrl;
    }

    public toggleDetached(): Promise<void> {
        if (this.isDetached) {
            return this.attachAsPopup();
        } else {
            return this.detachInNewWindow()
        }
    }

    public displayPopupAttached(): void {
        this._browserService.setPopupToAttached();
    }

    public displayPopupDeactivated(): void {
        this._browserService.setPopupToDetached();
    }

    public attachBrowserHandlers(): void {
        this._browserService.attachTabRemovedHandler(this.tabRemoveHandler.bind(this));
        this._browserService.attachWindowRemovedHandler(this.WindowRemovedHandler.bind(this));
        this._browserService.attachTabAttachedHandler(this.tabAttachedHandler.bind(this));
    }

    public attachAsPopup(): Promise<void> {
        return this._browserService.closeTab(this._aifexTab.id)
    }

    public onBrowserActionClicked(): void {
        this.attachAsPopup()
        .then(() => this._browserService.setPopupToAttached())
    }

    public detachInNewWindow(): Promise<void> {
        return new Promise((resolve, reject) => {
            if (!this._aifexWindow) {
                this._browserService.createWindow(this.aifexPageUrl)
                .then((windowId : number) => {
                    this._aifexWindow = new Window(windowId);
                    return this._browserService.getTabIdListOfWindow(windowId)
                })
                .then((tabIdList) => {
                    if (tabIdList.length === 0) {
                        return;
                    } else {
                        this._aifexTab = new Tab(tabIdList[0]);
                    }
                    resolve();
                })
                .then(() => this.displayPopupDeactivated())
            } else {
                resolve();
            }
        }).then(() => {
            if (!this._aifexTab) {
                return this._browserService.createTab(this._aifexWindow.id, this.aifexPageUrl)
                    .then((tabId: number) => {
                        this._aifexTab = new Tab(tabId);
                        return;
                    })
            } else {
                return;
            }
        })
        .then(() => {
            return this._browserService.focusTab(this._aifexTab.id)
        })

    }

    private tabRemoveHandler(tabId: number, windowId: number): void {
        if (tabId === this._aifexTab?.id) {
            this._aifexTab = undefined;
            this._aifexWindow = undefined;
            this.displayPopupAttached()
        }
    }

    private tabAttachedHandler(tabId: number, windowId: number): void {
        if (tabId === this._aifexTab?.id) {
            this._aifexWindow = new Window(windowId);
        }
    }

    private WindowRemovedHandler(windowId: number): void {
        if (windowId === this._aifexWindow?.id) {
            this._aifexWindow = undefined;
            this._aifexTab = undefined;
            this.displayPopupAttached()
        }
    }
}
