import { WebDriver } from 'selenium-webdriver';
import { Options } from 'selenium-webdriver/chrome';

type WebDriverWithExtension<T> = T & {
    readonly sbExtension: true;
};
interface Automation<D, O> {
    /**
     * Opens a new Sessionbox profile.
     *
     * @param {'temp' | 'cloud' | 'local'} sessionType - The type of session you wish to create.
     * @param {string} [targetUrl] - Optional. The URL you wish to open. Defaults to 'sessionbox.io'.
     * @param {WebDriverWithExtension} [driver] - Optional. The webdriver you wish to do the automation on. If not provided, a default option will be provided.
     * @returns {Promise<void>} A promise that resolves once the profile has been created and the desired URL has been opened in the browser.
     */
    openNewProfile: (sessionType: 'temp' | 'cloud' | 'local', targetUrl?: string, driver?: WebDriverWithExtension<D>) => Promise<WebDriverWithExtension<D>>;
    /**
     * Opens an existing Sessionbox profile.
     *
     * @param {string} profileId - The ID of the existing profile you wish to open.
     * @param {WebDriverWithExtension} [driver] - Optional. The webdriver you wish to do the automation on. If not provided, a default option will be provided.
     * @returns {Promise<void>} A promise that resolves once the existing profile has been opened and the desired URL has been loaded in the browser.
     */
    openExistingProfile: (profileId: string, driver?: WebDriverWithExtension<D>) => Promise<WebDriverWithExtension<D>>;
    /**
     * Creates a Webdriver with a Sessionbox extension and provided driver options.
     *
     * @param {Options} [options] - Optional. The options you wish to feed to the selenium chrome driver.
     * @returns {Promise<WebDriverWithExtension>} A promise that resolves once the driver is created.
     */
    createSessionBoxDriver: (options?: O) => Promise<WebDriverWithExtension<D>>;
}

declare enum ColorNames {
    RED = "red",
    PINK = "pink",
    PURPLE = "purple",
    DEEP_PURPLE = "deep purple",
    INDIGO = "indigo",
    LIGHT_BLUE = "light blue",
    CYAN = "cyan",
    TEAL = "teal",
    GREEN = "green",
    LIGHT_GREEN = "light green",
    LIME = "lime",
    YELLOW = "yellow",
    AMBER = "amber",
    ORANGE = "orange",
    DEEP_ORANGE = "deep orange",
    BROWN = "brown",
    GREY = "grey",
    BLUE_GREY = "blue grey"
}

interface Cookie {
    name: string;
    value: string;
    domain?: string;
    expirationDate?: number;
    hostOnly?: boolean;
    httpOnly?: boolean;
    path?: string;
    sameSite?: 'unspecified' | 'no_restriction' | 'lax' | 'strict';
    secure?: boolean;
    session?: boolean;
}

interface Profile {
    id: string;
    teamId: string;
    launchUrl: string;
    name: string;
    color: string;
    group: string;
    icon: string;
}

interface Endpoint {
    /**
     * Returns a list of all Sessionbox profiles.
     *
     * @returns {Promise<Profile[]>} A promise containing an array of Profile objects.
     */
    listProfiles: () => Promise<Profile[]>;
    /**
     * Return a Sessionbox profile by ID.
     * @param {string} profileID - The ID of the profile to retrieve.
     * @returns {Promise<Profile>} A Promise containing the Profile object corresponding to the provided ID.
     */
    getProfile: (profileId: string) => Promise<Profile>;
    /**
     * Creates a Sessionbox profile with the specified attributes.
     *
     * @param {string} color - Profile color.
     * @param {string} group - Profile group.
     * @param {string} name - Profile name.
     * @param {string} url - Profile URL.
     * @param {string} storageType - Profile storage type. Can be 'local' or 'cloud'.
     * @param {string} cookies - Profile cookies.
     * @returns {Promise<Profile>} A promise that resolves to the result of the profile creation.
     */
    createProfile: (color: ColorNames, group: string, name: string, url: string, storageType: 'local' | 'cloud', cookies: Cookie[]) => Promise<Profile>;
    /**
     * Returns an action token.
     *
     * @param action - Profile color.
     * @param profileId - Profile Id.
     * @param url - Profile URL.
     * @returns {Promise<string>} A promise that resolves to the created action token.
     */
    createActionToken: (action: string, profileId?: string, url?: string) => Promise<string>;
    /**
     * Deletes a Sessionbox profile by ID.
     *
     * @param {string} profileId - The ID of the profile to delete.
     */
    deleteProfile: (profileId: string) => Promise<void>;
    /**
     * Updates Sessionbox profile by ID.
     *
     * @param {string} profileId -The ID of the profile to update.
     * @param {string} color - Profile color (optional).
     * @param {string} group - Profile group (optional).
     * @param {string} name - Profile name (optional).
     * @param {string} sbProxyId - Id of proxy (optional).
     * @param {string} url - Profile URL (optional).
     * @returns {Promise<Profile>} A promise that resolves to the result of the updated profile.
     */
    updateProfile: (profileId: string, color?: ColorNames, group?: string, name?: string, sbProxyId?: string, url?: string) => Promise<void>;
    /**
     * Adds a proxy to Sessionbox.
     *
     * @param {string} name - Proxy name.
     * @param {string} type - Proxy type.
     * @param {string} username - Proxy username.
     * @param {string} password - Proxy password.
     * @param {string} ip - Proxy IP.
     * @param {string} port - Proxy port.
     * @param {string} teamId - Team ID (optional). If not provided, it will be saved to the personal account.
     */
    addProxy: (name: string, type: string, username: string, password: string, ip: string, port: string, teamId?: string) => Promise<any>;
    /**
     * Lists all proxies in Sessionbox.
     */
    listProxies: () => Promise<any>;
    /**
     * Deletes a proxy in Sessionbox by ID.
     *
     * @param proxyId - The ID of the proxy to delete.
     */
    removeProxy: (proxyId: string) => Promise<void>;
    /**
     * Lists all teams in Sessionbox.
     */
    listTeams: () => Promise<any>;
}

declare enum StorageType {
    CLOUD = "cloud",
    LOCAL = "local",
    TEMP = "temp",
    OPEN = "open"
}

interface Response {
    success: boolean;
    token: string;
}

/**
 * Initializes the SessionBox API and Automation instances.
 *
 * @param {string} apiKey - The API key for authentication.
 * @returns {{ sessionBoxAPI: Endpoint, sessionBoxAutomation: Automation }} An object containing initialized API and Automation instances.
 */
declare function sessionBoxInit(apiKey: string): {
    api: Endpoint;
    selenium: Automation<WebDriver, Options>;
};

export { ColorNames, Cookie, Profile, Response, StorageType, sessionBoxInit };
