import * as React from 'react';
import { Root } from 'react-dom/client';

type ManifestContentScript = ({
    world: "MAIN";
    persist_across_sessions?: boolean;
} | {
    world?: "ISOLATED";
    match_about_blank?: boolean;
    match_origin_as_fallback?: boolean;
    /**
     * https://developer.chrome.com/docs/extensions/mv3/content_scripts/#matchAndGlob
     */
    exclude_globs?: string[];
    include_globs?: string[];
}) & {
    matches: string[];
    /**
     * https://developer.chrome.com/docs/extensions/mv3/content_scripts/#matchAndGlob
     */
    exclude_matches?: string[];
    js?: string[];
    css?: string[];
    all_frames?: boolean;
    /**
     * https://developer.chrome.com/docs/extensions/mv3/content_scripts/#run_time
     */
    run_at?: "document_start" | "document_end" | "document_idle";
};

type PlasmoCSConfig = Omit<Partial<ManifestContentScript>, "js">;
/**
 * @deprecated use **PlasmoCSConfig** instead
 */
type PlasmoContentScript = PlasmoCSConfig;
type Async<T> = Promise<T> | T;
type Getter<T, P = any> = (props?: P) => Async<T>;
type InsertPosition = "beforebegin" | "afterbegin" | "beforeend" | "afterend";
type ElementInsertOptions = {
    element: Element;
    insertPosition?: InsertPosition;
};
type ElementInsertOptionsList = ElementInsertOptions[];
type GetElement = Getter<Element>;
type GetElementInsertOptions = Getter<ElementInsertOptions>;
type PlasmoCSUIOverlayAnchor = {
    element: Element;
    root?: Root;
    type: "overlay";
};
type PlasmoCSUIInlineAnchor = {
    element: Element;
    type: "inline";
    insertPosition?: InsertPosition;
    root?: Root;
};
type PlasmoCSUIAnchor = PlasmoCSUIOverlayAnchor | PlasmoCSUIInlineAnchor;
type PlasmoCSUIProps = {
    anchor?: PlasmoCSUIAnchor;
};
type PlasmoCSUIMountState = {
    document: Document;
    observer: MutationObserver | null;
    mountInterval: NodeJS.Timer | null;
    isMounting: boolean;
    isMutated: boolean;
    /**
     * Used to quickly check if element is already mounted
     */
    hostSet: Set<Element>;
    /**
     * Used to add more metadata to the host Set
     */
    hostMap: WeakMap<Element, PlasmoCSUIAnchor>;
    /**
     * Used to align overlay anchor with elements on the page
     */
    overlayTargetList: Element[];
};
type PlasmoGetRootContainer = (props: {
    mountState?: PlasmoCSUIMountState;
} & PlasmoCSUIProps) => Async<Element>;
type PlasmoGetOverlayAnchor = GetElement;
type PlasmoGetOverlayAnchorList = Getter<NodeList>;
type PlasmoGetInlineAnchor = GetElement | GetElementInsertOptions;
type PlasmoGetInlineAnchorList = Getter<NodeList | ElementInsertOptionsList>;
type PlasmoMountShadowHost = (props: {
    mountState?: PlasmoCSUIMountState;
    shadowHost: Element;
} & PlasmoCSUIProps) => Async<void>;
type PlasmoGetShadowHostId = Getter<string, PlasmoCSUIAnchor>;
type PlasmoGetStyle = Getter<HTMLStyleElement, PlasmoCSUIAnchor & {
    sfcStyleContent?: string;
}>;
type PlasmoGetSfcStyleContent = Getter<string>;
/**
 * @return a cleanup unwatch function that will be run when unmounted
 */
type PlasmoWatchOverlayAnchor = (updatePosition: () => Promise<void>) => (() => void) | void;
type PlasmoCSUIContainerProps = {
    id?: string;
    children?: React.ReactNode;
    watchOverlayAnchor?: PlasmoWatchOverlayAnchor;
} & PlasmoCSUIProps;
type PlasmoCSUIJSXContainer = (p?: PlasmoCSUIContainerProps) => React.JSX.Element;
type PlasmoCSUIHTMLContainer = (p?: PlasmoCSUIContainerProps) => HTMLElement;
type PlasmoCreateShadowRoot = (shadowHost: HTMLElement) => Async<ShadowRoot>;
type PlasmoRender<T> = (props: {
    createRootContainer?: (p?: PlasmoCSUIAnchor) => Async<Element>;
} & PlasmoCSUIProps, InlineCSUIContainer?: T, OverlayCSUIContainer?: T) => Async<void>;
type PlasmoCSUIWatch = (props: {
    render: (anchor: PlasmoCSUIAnchor) => Async<void>;
    observer: {
        start: (render: (anchor?: PlasmoCSUIAnchor) => void) => void;
        mountState: PlasmoCSUIMountState;
    };
}) => void;
type PlasmoCSUI<T> = {
    default: any;
    getStyle: PlasmoGetStyle;
    getSfcStyleContent: PlasmoGetSfcStyleContent;
    getShadowHostId: PlasmoGetShadowHostId;
    getOverlayAnchor: PlasmoGetOverlayAnchor;
    getOverlayAnchorList: PlasmoGetOverlayAnchorList;
    getInlineAnchor: PlasmoGetInlineAnchor;
    getInlineAnchorList: PlasmoGetInlineAnchorList;
    getRootContainer: PlasmoGetRootContainer;
    createShadowRoot: PlasmoCreateShadowRoot;
    watchOverlayAnchor: PlasmoWatchOverlayAnchor;
    mountShadowHost: PlasmoMountShadowHost;
    render: PlasmoRender<T>;
    watch: PlasmoCSUIWatch;
};

export type { PlasmoCSConfig, PlasmoCSUI, PlasmoCSUIAnchor, PlasmoCSUIContainerProps, PlasmoCSUIHTMLContainer, PlasmoCSUIJSXContainer, PlasmoCSUIMountState, PlasmoCSUIProps, PlasmoCSUIWatch, PlasmoContentScript, PlasmoCreateShadowRoot, PlasmoGetInlineAnchor, PlasmoGetInlineAnchorList, PlasmoGetOverlayAnchor, PlasmoGetOverlayAnchorList, PlasmoGetRootContainer, PlasmoGetSfcStyleContent, PlasmoGetShadowHostId, PlasmoGetStyle, PlasmoMountShadowHost, PlasmoRender, PlasmoWatchOverlayAnchor };
