import WindowOption from "./WindowOption";

export function createWindow(options: WindowOption): Promise<chrome.windows.Window> {
    return new Promise((resolve, reject) => {
        chrome.windows.create(options, (window: chrome.windows.Window) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve(window);
            }
        });
    });
}

export function getCurrentWindow(): Promise<chrome.windows.Window> {
    return new Promise((resolve, reject) => {
        chrome.windows.getCurrent({populate: true}, (window: chrome.windows.Window) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error)
            }
            resolve(window);
        })
    });
}

export function getTabIdListOfWindow(windowId): Promise<number[]> {
    return new Promise((resolve, reject) => {
        chrome.windows.get(windowId, {populate: true}, (window: chrome.windows.Window) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error)
            }
            const tabs = window.tabs;
            resolve(tabs.map(tab => tab.id));
        })
    })
}

export function getWindowById(windowId: number):Promise<chrome.windows.Window> {
    return new Promise((resolve, reject) => {
        chrome.windows.get(windowId, {populate: true}, (window:chrome.windows.Window) => {
                const error = chrome.runtime.lastError;
                if (error) {
                    reject(error);
                } else {
                    resolve(window);
                }
            }
        );
    });
}

export function updateWindowById(windowId: number, options : {drawAttention: boolean,focused: boolean}):Promise<void> {
    return new Promise((resolve, reject) => {
        chrome.windows.update(windowId, options, (window: chrome.windows.Window) => {
                const error = chrome.runtime.lastError;
                if (error) {
                    reject(error);
                } else {
                    resolve();
                }
            }
        );
    });
}

export function getTabById(tabId: number):Promise<chrome.tabs.Tab> {
    return new Promise( (resolve, reject) => {
        chrome.tabs.get(tabId, (tab:chrome.tabs.Tab) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve(tab);
            }
        });
    });
}

export function removeWindowById(windowId: number): Promise<void> {
    return new Promise( (resolve, reject) => {
        chrome.windows.remove(windowId, () => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        });
    })
}

export function createTab(options:{windowId:number, index?:number, url:string }): Promise<chrome.tabs.Tab> {
    return new Promise((resolve, reject) => {
        chrome.tabs.create(options, (tab: chrome.tabs.Tab) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve(tab);
            }
        });
    })
}

export function removeTabs(tabIds:number[]): Promise<void> {
    return new Promise((resolve, reject) => {
        chrome.tabs.remove(tabIds, () => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        })
    })
}

export function focusTab(tabId): Promise<void> {
    return new Promise((resolve, reject) => {
        chrome.tabs.update(tabId, {active: true} ,() => {
            const error = chrome.runtime.lastError;
            if (error) {
                return reject(error);
            } else {
                return resolve();
            }
        })
    })
}

export function executeTabScript(tabId: number): Promise<boolean> {
    console.log('executre script for id:', tabId);
    return new Promise((resolve, reject) => {
        chrome.tabs.executeScript(tabId, {file: 'tabScript.js'}, () => {
            const error = chrome.runtime.lastError;
            if (error) {
                // console.log("checking", error)

                const errorMsg = error.message;
                const chromeStartPage = 'Cannot access contents of url "chrome-search://local-ntp/local-ntp.html';
                const chromeExtensionPage = 'Cannot access a chrome:// URL';
                // Not an error, happens when a chrome:// tab is opened in the window

                if (errorMsg.startsWith(chromeStartPage) || errorMsg.startsWith(chromeExtensionPage)) {
                    resolve(false);
                } else {
                    reject(errorMsg);
                }
            }
            else {
                resolve(true);
            }
        });
    });
}

export function sendMessageToExtension(message={}, messageKind : string): Promise<any> {
    const messageData = Object.assign(message, {kind: messageKind});

    return new Promise((resolve, reject) => {
        chrome.runtime.sendMessage(messageData, undefined, (response) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve(response);
            }
        });
    });
}


export function sendMessageToTab(message={}, messageKind : string, tabId: number): Promise<any> {
    const messageData = Object.assign(message, {kind: messageKind});

    // console.log('ChromePromise will send : ', message, messageKind);
    // console.log('toId : ', tabId);

    return new Promise((resolve, reject) => {
        chrome.tabs.sendMessage(tabId, messageData, undefined, (response) => {
            const error = chrome.runtime.lastError;
            if (error) {
                reject(error);
            } else {
                resolve(response);
            }
        });
    });
}

export function takeScreenshot(): Promise<string> {
    return new Promise((resolve, reject) => {
        chrome.tabs.captureVisibleTab(this.WindowId, {format : "jpeg",quality : 100}, dataImage => {
            const error = chrome.runtime.lastError;
            if (error) {
                console.error(error);
                reject(error);
            } else {
                resolve(dataImage)
            }
        })
    })
}


export function captureStreamOnWindow() : Promise<{stream : MediaStream, id: number}> {
    return new Promise((resolve, reject) => {
        const id = chrome.desktopCapture.chooseDesktopMedia(["window"], (streamId)=> {
            const chromeError = chrome.runtime.lastError;
            if (chromeError) {
                reject(chromeError);
            } else {
                if (!streamId) {
                    reject("canceled");
                } else {
                    const n = navigator as any;
                    n.webkitGetUserMedia({
                        video: {
                        mandatory: {
                            chromeMediaSource: 'desktop',
                            chromeMediaSourceId: streamId,
                            maxWidth:screen.width,
                            maxHeight:screen.height} }
                    }, (stream) => {
                        resolve({stream, id});
                    }, (error) => {
                        reject(error);
                    });
                }
            }
        });
    })
}

