import type { ActionObject, BaseSchemaScoped, BaseSchemaWithoutType, ReactPropsBase, RendererProps, SchemaBoolean, SchemaClassName, SchemaExpression } from 'jamis-core';
import type { CSSProperties, ReactNode } from 'react';
import type React from 'react';
import type { Location } from 'history';
import type { SchemaApi, SchemaCollection, SchemaObject, TourConfig } from '../types';
import type { IAppStore } from './AppStore';
export interface RouterHook {
    /**
     * 检查是否拦截, `true`表示要拦截, 执行failback逻辑; `false`代表放过
     */
    checkExpression: SchemaBoolean;
    /** 拦截后发起的动作 */
    failbackAction?: ActionObject | ActionObject[];
    /**
     * 是否停止渲染路由的schema, 默认是 true.
     * 当你配置了failbackAction, 而没有配置 failbackSchema时, 阻止schema的渲染
     */
    stopRender?: boolean;
    /** 拦截后使用的schema */
    failbackSchema?: SchemaObject;
}
export interface AppRouter {
    /**
     * 菜单文字
     */
    label?: string;
    /**
     * 菜单图标，比如： FileOutlined
     */
    icon?: string;
    /**
     * 路由规则, 比如：/banner/:id。当地址以 / 打头，则不继承上层的路径，否则将集成父级页面的路径。
     * 也可以是外部链接
     */
    url?: string;
    /**
     * 单纯的地址。可以设置外部链接。
     */
    link?: string;
    /**
     * 当url或者link是绝对地址时, 设置打开策略
     */
    target?: '_self' | '_blank' | '_parent' | '_top';
    /**
     * 当match url 时跳转到目标地址.没有配置 schema 和 shcemaApi  时有效.
     */
    redirect?: string;
    /**
     * 当match url 转成渲染目标地址的页面.没有配置 schema 和 shcemaApi  时有效.
     */
    rewrite?: string;
    /**
     * 不要出现多个，如果出现多个只有第一个有用。在路由找不到的时候作为默认页面。
     */
    isDefaultPage?: boolean;
    /**
     * 二选一，如果配置了 url 一定要配置。否则不知道如何渲染。
     */
    schema?: SchemaCollection;
    schemaApi?: SchemaApi;
    /**
     * 页面schema提供者, 和前面的schema/schemaApi互斥, 优先级从前往后
     * @deprecated 请使用`schemaApi.fetcherProvider`来替代
     */
    schemaProvider?: (data: JSObject, store: IAppStore) => Promise<SchemaCollection>;
    /**
     * 是否嵌套在父路由里
     */
    nested?: boolean;
    /**
     * 支持多层级。
     */
    children?: Array<AppRouter>;
    /** 是否默认展开, 只对有非叶子节点有效, 默认不展开 */
    initialOpen?: boolean;
    /**
     * 菜单上的类名
     */
    className?: SchemaClassName;
    /**
     * 是否在导航中可见，适合于那种需要携带参数才显示的页面。比如具体某个数据的编辑页面。
     */
    visible?: boolean;
    /**
     * 默认是自动，即：自己选中或者有孩子节点选中则展开。
     * 如果配置成 always 或者配置成 true 则永远展开。
     * 如果配置成 false 则永远不展开。
     */
    /** 内部使用, 不可在schema里使用, 使用`url` */
    path?: string;
    /** 内部使用, 暂时似乎无用 */
    index?: number;
    /** 路由唯一id, 未指定时使用guid */
    id?: string;
    /**
     * 路由的hooks配置
     */
    hooks?: Record<'beforeEnter', RouterHook | RouterHook[]>;
    /**
     * 运行后有效的beforeEnter hook
     */
    __activeHookBeforeEnter?: RouterHook;
    [key: string]: any;
}
/**
 * @deprecated 请使用 AppRouter 替代
 */
export type AppPage = AppRouter;
/**
 * App 渲染器，适合 JSSDK 用来做多页渲染。
 *
 */
export interface AppSchema extends BaseSchemaScoped {
    /**
     * 指定为 app 类型。
     */
    type: 'app';
    api?: SchemaApi;
    /**
     * 系统名称
     */
    brandName?: SchemaCollection;
    /**
     * brand的样式类名
     */
    brandClassName?: SchemaClassName;
    /**
     * brand点击跳转的url
     */
    brandLink?: string;
    brankLinkClassName?: SchemaClassName;
    /**
     * logo 图片地址，可以是 svg。
     */
    logo?: string;
    /**
     * 顶部区域
     */
    header?: SchemaCollection;
    /**
     * 元素`.cxd-Layout-header`的样式类
     */
    headerClassName?: SchemaClassName;
    headerBarClassName?: SchemaClassName;
    /**
     * 内容区(包括aside)样式类名
     */
    contentClassName?: SchemaClassName;
    contentStyle?: React.CSSProperties;
    /**
     * 内容体部分(不包括aside)样式类名
     */
    bodyClassName?: SchemaClassName;
    bodyStyle?: React.CSSProperties;
    /**
     * 边栏
     */
    aside?: {
        /**
         * 是否展示
         */
        visible?: SchemaBoolean;
        visibleOn?: SchemaExpression;
        /**
         * 边栏菜单前面的区域
         */
        beforeRegion?: SchemaCollection;
        /**
         * 边栏菜单后面的区域
         */
        afterRegion?: SchemaCollection;
        /**
         * 边栏菜单的样式类
         */
        className?: SchemaClassName;
        style?: CSSProperties;
        navClassName?: SchemaClassName;
        navStyle?: CSSProperties;
        /**
         * 子菜单列表样式类
         */
        subListClassName?: SchemaClassName;
        /**
         * 边栏菜单项的样式类
         */
        linkClassName?: SchemaClassName;
        /**
         * 是否显示收起/展开按钮, 默认是 true
         */
        showFoldBtn?: boolean;
        foldBtnClassName?: SchemaClassName;
    };
    /**
     * 页面集合。
     */
    pages?: Array<AppRouter> | AppRouter;
    /**
     * 所有路由页面的公共样式类
     */
    pageClassName?: SchemaClassName;
    /**
     * 所有路由页面的公共样式
     */
    pageStyle?: CSSProperties;
    /**
     * 底部区域。
     */
    footer?: SchemaCollection;
    footerClassName?: SchemaClassName;
    /**
     * css 类名。
     */
    className?: SchemaClassName;
    /**
     * 显示面包屑路径。
     */
    showBreadcrumb?: boolean;
    showBreadcrumbOn?: SchemaExpression;
    /**
     * 显示面包屑完整路径。
     */
    showFullBreadcrumbPath?: boolean;
    showFullBreadcrumbPathOn?: SchemaBoolean;
    /**
     * 显示面包屑首页路径。
     */
    showBreadcrumbHomePath?: boolean;
    showBreadcrumbHomePathOn?: boolean;
    breadcrumbClassName?: SchemaClassName;
    /**
     * 父路由只是展开, 不去跳转
     */
    parentToggleExpand?: boolean;
    /**
     * 控制是否显示菊花
     */
    showLoading?: boolean;
    showLoadingOn?: SchemaExpression;
    /**
     * 移动端下的左右抽屉的样式类
     */
    navDrawerClassName?: SchemaClassName;
    /**
     * 移动端下的左右抽屉内容区的样式类
     */
    navDrawerContentClassName?: SchemaClassName;
    tour?: boolean;
    tourOn?: SchemaBoolean;
    tourConfig?: TourConfig;
}
/**
 * 路由占位组件
 */
export interface AppRouterSchema extends BaseSchemaWithoutType {
    type: 'app-router';
    routerId: string;
}
export interface AppProps extends RendererProps, Omit<AppSchema, 'type' | 'className' | 'data'> {
    children?: JSX.Element | ((props?: any) => JSX.Element);
    store: IAppStore;
    headerClassName?: string;
    contentClassName?: string;
    bodyClassName?: string;
    breadcrumbClassName?: string;
    footerClassName?: string;
    pageClassName?: string;
    aside: Required<AppSchema>['aside'];
    location?: Location;
}
export interface AppRouterProps extends RendererProps, AppRouterSchema {
    routerId: string;
}
export interface AsideNavProps extends ReactPropsBase {
    id?: string;
    subListClassName?: SchemaClassName;
    /** 是否收缩起来 */
    folded?: boolean;
    navigations: Array<NavigationObject>;
    /**
     * 父路由是否可以展开/收起
     */
    expandable?: boolean;
    /**
     * 父路由初始展开层级
     */
    expandInitialLevel?: number;
    renderLink: (item: {
        link: LinkItem;
        key: string | number;
        toggleExpand?: (link: LinkItem, e?: React.MouseEvent) => void;
        depth?: number;
    }) => ReactNode;
    /**
     * 是否选中
     */
    checkIsActive: (link: LinkItem) => boolean | undefined;
    checkIsOpen: (link: LinkItem) => boolean;
}
export interface AsideNavLinkProps {
    folded?: boolean;
    link: LinkItem;
    depth: number;
    key: string | number;
    /**
     * 父路由只是展开, 不去跳转。
     */
    parentToggleExpand?: boolean;
    linkClassName?: SchemaClassName;
    filterClassName: (className: SchemaClassName) => string | undefined;
    /**
     * 渲染出内部的路由链接, 为了兼容examples里使用react-router的场景.
     * 此时不需要设置`onNavClick`
     */
    renderRouterLink?: (linkClassName: string, children: JSX.Element[]) => JSX.Element;
    /**
     * 内部路由点击跳转逻辑, 当透传renderRouterLink时可以不用传递
     */
    onNavClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
    /**
     * 展开父项的函数, 如果不传, 表示默认全部展开, 无法收缩
     */
    toggleExpand?: (link: LinkItem, e?: React.MouseEvent<Element, MouseEvent> | undefined) => void;
}
export interface NavigationObject {
    label: string;
    children?: LinkItem[];
    prefix?: JSX.Element;
    affix?: JSX.Element;
    className?: SchemaClassName;
    path?: string;
    initialOpen?: boolean;
    active?: boolean;
    open?: boolean;
    [propName: string]: any;
}
export interface LinkItem {
    id?: number;
    label: string;
    hidden?: boolean;
    open?: boolean;
    active?: boolean;
    className?: SchemaClassName;
    children?: Array<LinkItem>;
    path?: string;
    target?: '_self' | '_blank' | '_parent' | '_top';
    icon?: string;
    visible?: boolean;
    badge?: string;
    badgeClassName?: SchemaClassName;
    component?: React.ComponentType;
}
