import React, { ReactNode } from 'react';
import ReactGridLayout from 'react-grid-layout';
import { ISchema } from '@formily/next';
/**
 * 页面生成器验证器
 */
export class PageCreater extends React.Component<PageCreaterProps, any> {}
/**
 * 页面生成器-画布
 */
export class DragLayoutCanvas extends React.Component<DragLayoutCanvasProps, any> {}
/**
 * 页面生成器-组件列表
 */
export class ComList extends React.Component<ComListProps, any> {}
/**
 * 页面生成器-属性面板
 */
export class AttrPanel extends React.Component<AttrPanelProps, any> {}
/**
 * 页面生成器-编辑器套件
 */
export class Editor extends React.Component<EditProps, any> {}
/**
 * 页面生成器-编辑器套件
 */
export class AttributesPanel extends React.Component<AttributesPanelProps, any> {}
/**
 * 页面生成器-左页签编辑画布
 */
export class HorizontalEditor extends React.Component<EditorBaseProps, any> {}
/**
 * 页面生成器-无页签编辑画布
 */
export class SingleEditor extends React.Component<EditorBaseProps, any> {}
/**
 * 页面生成器-上页签编辑画布
 */
export class VerticalEditor extends React.Component<EditorBaseProps, any> {}
/**
 * 页面生成器-左页签浏览模式画布
 */
export class HorizontalLayoutView extends React.Component<ViewBaseProps, any> {}
/**
 * 页面生成器-无签浏览模式画布
 */
export class SingleLayoutView extends React.Component<ViewBaseProps, any> {}
/**
 * 页面生成器-上页签浏览模式画布
 */
export class VerticalLayoutView extends React.Component<ViewBaseProps, any> {}
/**
 *	获取组件类方法
 * @param comName 组件名称
 * @param importFrom 引用方式
 * @param customGetComRequire 自定义引用函数
 */
declare function getComRequire(
	comName: string,
	importFrom?: 'npm' | 'local',
	customGetComRequire?: (comName: string, importFrom: 'npm' | 'local') => React.ComponentClass
): React.ComponentClass;
/**
 * 触发浏览器resize事件
 * @param time 延迟触发时间，毫秒
 */
declare function dispatchResizeEvent(time: number): void;
/**
 * 业务组件
 */
export class ComponentBase extends React.Component<ComponentBaseProps, any> {
	/**
	 * 属性面板组件
	 */
	static AttrPanel?: ComAttrPanel;
	/**
	 * 获取schema方法
	 */
	static getSchema?: ({ pageProps, config, request }: SchemaProps) => ISchema;
	/**
	 * 组件配置数据
	 */
	static config?: widget;
	/**
	 * 组件属性面板数据统一校验规则
	 * @param attributes 属性面板数据
	 * @returns 返回是否校验成功
	 */
	static validate?: (attributes: object) => boolean;
	/**
	 * schema自定义表单组件传递，在使用schema时，若有自定组件，则使用此参数 exp:{custom1:Custom1,custom2:Custom2}
	 */
	static CustomScCom?: object;
}
export interface EditorBaseProps {
	onTabChange?: (params: {
		tabSelectedIndex?: string | number;
		currentPageConfig: pageConfig;
		selected?: string | number;
	}) => void;
	tabSelectedIndex?: string | number;
	appPageConfig?: templateConfig;
	onClickBlank?: () => void;
	selected?: string | number;
	droppingItem?: any;
	isDroppable?: boolean;
	isEdit?: boolean;
	onChange?: (pageConfig: pageConfig) => void;
	onWidgetSelect?: (id: string) => void;
	pageProps?: object;
	jumpto?: (path: string) => void;
	/**
	 * 删除某个组件回调
	 */
	onClose?: (index?: number) => void;
	request?: any;
	addNewTab?: () => void;
	layoutProps?: object;
}
export interface ViewBaseProps {
	setSelectId?: (selectId?: string | number) => void;
	appPageConfig?: templateConfig;
	selectId?: string | number;
	pageProps?: object;
	onChange?: (pageConfig?: pageConfig, callback?: () => void) => void;
	request?: any;
	jumpto?: (path: string) => void;
	hideComList?: string[];
}
/**
 * 业务组件属性表单生成器属性
 */
export interface SchemaProps {
	/**
	 * 页面参数
	 */
	pageProps?: any;
	/**
	 * 所选组件配置数据
	 */
	config?: widget;
	/**
	 * 数据请求体
	 */
	request?: any;
}
/**
 * 业务组件中的属性面板
 */
export class ComAttrPanel extends React.Component<ComAttrPanelProps, any> {}
/**
 * 业务组件中的属性面板中的接收属性
 */
export interface ComAttrPanelProps {
	/**
	 * 页面属性
	 */
	pageProps?: any;
	/**
	 * 所选组件配置
	 */
	config?: widget;
	/**
	 * 数据请求体
	 */
	request?: any;
	/**
	 * 属性值
	 */
	attributes?: any;
	/**
	 * 表单属性发生改变时回调
	 */
	onChange?: (values: object) => void;
}
/**
 * 业务组件属性接口
 */
export interface ComponentBaseProps {
	/**
	 * 是否是编辑模式
	 */
	isEdit?: boolean;
	/**
	 * (path)=>void页面跳转操作
	 */
	jumpto?: (path: string) => void;
	/**
	 * 父页面公共属性
	 */
	pageProps?: object; //父页面公共属性
	/**
	 * 父页面存储的分组属性
	 */
	widgetsProps?: object;
	/**
	 * 添加或修改父页面公共属性(pageProps)，可用来实现组件间数据联动
	 */
	setPageState?: (state: object) => {};
	/**
	 * 添加或修改父页面分组属性
	 */
	setWidgetsState?: (state: object) => {};
	/**
	 * 组件配置数据
	 */
	config?: widget;
	/**
	 * 数据请求体
	 */
	request?: any;
	/**
	 * 组件内部可调用此方法修改组件配置数据
	 */
	onConfigChange?: (config: widget) => void;
	/**
	 * 切换当前组件全屏状态，返回 true/false 全屏/正常
	 */
	toggleFullScreen?: () => boolean;
	/**
	 * 获取当前组件是否全屏状态，返回 true/false 全屏/正常,可在初始化时调用
	 */
	getFullScreenState?: () => boolean;
	/**
	 * 当前业务组件选中回调，容器组件使用此属性
	 */
	onSelect?: (id: string) => void;
	/**
	 * 获取组件句柄类
	 * */
	getComRequire?: (
		comName: string,
		importFrom?: 'npm' | 'local',
		customGetComRequire?: (comName: string, importFrom: 'npm' | 'local') => React.ComponentClass
	) => React.ComponentClass;
	/**
	 * 自定义导入组件类方法,请参考util.js中的getComRequire实现此方法
	 * (comName, importFrom)=>component Class
	 */
	customGetComRequire?: (comName: string, importFrom: string) => React.ComponentClass;
	/**
	 * 获取组件基础属性配置
	 */
	getBaseAttributes?: () => object;
	/**
	 * 当前画布选中的组件，容器组件使用此属性
	 */
	selectedId?: string;
	/**
	 * 同级所有组件的集合，容器组件使用此属性
	 */
	allWidgets?: widget[];
	/**
	 * 容器组件间，其内部业务组件互相拖拽，引发业务组件迁移时，调用此方法
	 */
	onAllWidgetsChangeByCom?: (allWidgets: widget[], callback: () => void, isUpdateService: boolean) => void;
	/**
	 * 容器组件使用此属性，用来判断父是否允许拖入
	 */
	dragPanelIsDroppable?: boolean;
}
export declare type attrConfigItem = {
	name?: string;
	key?: string;
	render?: (selectItem?: widget, pageConfig?: pageConfig, templateData?: object) => ReactNode;
};
export declare type layoutListItem = {
	label?: string;
	key?: 'single' | 'vertical' | 'horizontal';
	img?: string;
};
/**
 * 组件配置
 */
export declare type widget = {
	/**
	 * 组件布局信息
	 */
	layouts?: ReactGridLayout.Layout;
	/**
	 * 组件实例化后的id，等于config.layouts.lg.i。此值无需设置，在创建组件实例时会自动赋值
	 */
	id: string;
	/**
	 * 组件列表上组件的悬浮信息
	 */
	title?: string;
	/**
	 * 组件列表若有图标，icon表示此图标（需求待定，预留属性）
	 */
	icon?: string;
	/**
	 * 组件的类型，若是npm发布组件，则填写为npm分组/后部分
	 * exp:@riil-uicbb/component-template,则type为component-template
	 */
	type: string;
	/**
	 * 组件来源 npm/local
	 */
	importFrom?: 'npm' | 'local';
	/**
	 * 画布上唯一的组件，即一个画布上只能拖拽上一个这样的组件
	 */
	isOnlyOne?: boolean;
	/**
	 * 属性面板对应属性，此属性对应AttrPanel内实现的各种数值编辑组件
	 */
	attributes?: object;
	/**
	 * 属性面板组件容器公共属性
	 * 默认值- {paddingLeft: 8,paddingTop: 8,paddingRight: 8,paddingBottom: 8}
	 */
	comContainerAttributes?: object;
	/**
	 * 组件所依赖的属性，key为属性值，info为缺少依赖时组件显示的文案。
	 * 依赖属性由pageProps传入组件。
	 * 依赖性验证由生成器完成，组件无需关注
	 */
	dependentProps?: { key: string; info: string }[];
	/**
	 * 组件对外提供的属性，通过setPageState，将属性发布到生成器公共属性状态中，作为公共依赖使用。
	 * 生成器会在组件拖拽创建后，自动将此属性以及默认值发布到公共状态中。
	 */
	publishProps?: { key: string; defaultValue: string }[];
};
/**
 * 组件列表单项数据
 * type 组件类型
 * importFrom 组件来源 npm:来源@riil-uicbb/域下的npm包；local： 来源本地src/components组件
 */
export declare type comListChild = {
	/**
	 * 组件名称
	 */
	name?: string;
	/**
	 * 组件图标
	 */
	icon?: string;
	/**
	 * 组件类型
	 */
	type?: string;
	/**
	 * 组件来源 npm:来源@riil-uicbb/域下的npm包；local： 来源本地src/components组件
	 */
	importFrom?: 'npm' | 'local';
};
/**
 * 组件列表单项数据
 * key 分组key
 * title 分组名称
 * children 组件列表
 */
export declare type comListItem = {
	key: string;
	title: string;
	children: comListChild[];
};

/**
 * 页面配置
 */
export declare type pageConfig = {
	/**
	 * 页面id
	 */
	pageId?: string;
	/**
	 * 名称
	 */
	pageName?: string;
	/**
	 * 组件配置集合
	 */
	widgets?: widget[];
	/**
	 * 布局配置
	 */
	layoutConfig?: {
		cols?: number; //默认栅格为24格
		rowHeight?: number; //高度比为4倍
		margin?: [x?: number, y?: number]; //默认间隔
		measureBeforeMount?: boolean; //如果为true，画布将在装入组件之前测量容器宽度。
		isFitHeight?: boolean; //是否一屏显示页面内组件。true 时会按屏幕的高度，按 widgets 中高度比例，适配各个组件的高度；false 时，会严格按照 widgets 中配置的高度显示组件
		isShowGrid?: boolean; //编辑模式是否显示网格
	};
};
/**
 * 页面配置
 */
export declare type templateConfig = {
	/**
	 * 页面id
	 */
	pageId?: string;
	/**
	 * 名称
	 */
	pageName?: string;
	configs?: pageConfig[];
};
/**
 * 画布属性
 */
export interface DragLayoutCanvasProps {
	/**
	 * ResponsiveReactGridLayout组件属性
	 */
	layoutProps?: object;
	/**
	 * 当前选中项id
	 */
	selectedId?: string;
	/**
	 * 子组件选中回调(id)=>void
	 */
	onSelect?: (id: String) => void;
	/**
	 * 是否是编辑模式
	 */
	isEdit?: boolean;
	/**
	 *(widget[])=>void切换布局，增加组件，删除组件回调,将组件配置数据传出
	 */
	onChange?: (widgets: widget[]) => void;
	/**
	 *(pageConfig)=>{}装载布局回调,将页面配置数据传出
	 */
	allPageOnChange?: (pageConfig: pageConfig) => void;
	/**
	 * 页面顶级参数，例如业务详情页面的业务appId将放在此属性中，供组件以及页面使用
	 */
	pageProps?: object;
	/**
	 * 在开发npm包组件时需用到此属性。面板使用者无需使用此属性
	 */
	ExpCom?: React.ComponentClass;
	/**
	 * 应用框架级数据请求方法，用来实现数据请求，参考 {request} from 'ice'
	 */
	request?: any;
	/**
	 * (path)=>void页面跳转操作
	 */
	jumpto?: (path: string) => void;
	/**
	 * 画布要展示内容的配置数据
	 */
	pageConfig?: pageConfig;
	/**
	 * 自定义导入组件类方法,请参考util.js中的getComRequire实现此方法
	 * (comName, importFrom)=>component Class
	 */
	customGetComRequire?: (comName: string, importFrom: string) => React.ComponentClass;
	/**
	 *画布外层dom对象，用来实现自动适配高度的功能
	 */
	parentDOM?: HTMLElement;
}
/**
 * 组件列表属性
 */
export interface ComListProps {
	/**
	 * 组件列表数据exp:[{key:'workbench',title:'工作台'，children:[{type: 'component-exp-alarm-list', importFrom: 'npm',icon:'help'}]  }],
	 * */
	comList?: comListItem[];
	/**
	 * 在开发npm包组件时需用到此属性。面板使用者无需使用此属性
	 */
	ExpCom?: React.ComponentClass;
	/**
	 * 当组件图标拖拽开始时回调
	 * config为拖拽组件的配置数据，e为鼠标event
	 */
	onItemDragStart?: (config: widget, e: MouseEvent) => void;
	/**
	 * 自定义导入组件类方法,请参考util.js中的getComRequire实现此方法
	 * (comName, importFrom)=>component Class
	 */
	customGetComRequire?: (comName: string, importFrom: string) => React.ComponentClass;
	/**
	 * 透传折叠面板属性
	 */
	collapseProps?: object;
}
export interface EditProps {
	/**
	 * 组件列表数据exp:[{key:'workbench',title:'工作台'，children:[{type: 'component-exp-alarm-list', importFrom: 'npm',icon:'help'}]  }],,
	 * */
	comList?: comListItem[];
	/**
	 * 透传给DragLayoutCanvas的公共属性
	 */
	pageProps?: object;
	/**
	 *应用框架级数据请求方法，用来实现数据请求，参考 {request} from 'ice'
	 */
	request?: any;
	/**
	 * 页面配置数据
	 */
	appPageConfig?: templateConfig;
	/**
	 * ResponsiveReactGridLayout组件属性
	 */
	layoutProps?: object;
	/**
	 * (path)=>{}页面跳转操作
	 */
	jumpto?: (path: string) => void;
	/**
	 * 从列表添加组件、删除组件、修改属性面板、拖拽组件位置、修改组件大小触发回调
	 * (pageConfig)=>{}
	 */
	onChange?: (templateConfig: templateConfig) => void;
	/**
  * attrConfig:属性面板分页签数据，可自定义扩展，自定义扩展数据中的render为属性面板自定义实例
  * @example [
	 { name: '模板设置', key: 'template' },
	 { name: '页面设置', key: 'page' },
	 { name: '组件设置', key: 'component' },
	 { name: '自定义', key: 'custom',render:(selectWidget,currentPage,template)=><Button>{selectWidget?.id}</Button> },
   ] 
  * layoutList 切换分页布局属性，目前支持一下三种分页布局方式
   @example [
	 {
	   key: LAYOUT_TYPE.horizontal,
	   label: '左侧页签',
	   img: 'hlayout.png',
	 },
	 {
	   key: LAYOUT_TYPE.vertical,
	   label: '上页签',
	   img: 'vlayout.png',
	 },
	 {
	   key: LAYOUT_TYPE.single,
	   label: '无页签',
	   img: 'slayout.png',
	 },
   ]
  * noDataImgSrc 无数据组件图标路径
   @example '/noDataImg/tableNotData.svg'
  * imgPath 布局属性组件图片路径
   @example '/img/uicbb/layout/'
  * tabProps 透传tab页签属性
  */
	attributeProps?: object;
	/**
	 * 组件列表属性
	 * {collapseProps - 折叠面板组件属性透传}
	 */
	comListProps?: object;
	/**
	 * 自定义导入组件类方法,请参考util.js中的getComRequire实现此方法
	 * (comName, importFrom)=>component Class
	 */
	customGetComRequire?: (comName: string, importFrom: string) => React.ComponentClass;
}
/**
 * 属性面板属性
 */
export interface AttrPanelProps {
	/**
	 * 画布的配置数据
	 */
	pageConfig?: pageConfig;
	/**
	 * 当前选中组件id
	 */
	selectId?: string;
	/**
	 * (pageConfig)=>void属性面板发生改变时的回调
	 */
	onChange?: (pageConfig: pageConfig) => void;
	/**
	 * 在开发npm包组件时需用到此属性。面板使用者无需使用此属性
	 */
	ExpCom?: React.ComponentClass;
	/**
	 * 应用框架级数据请求方法，用来实现数据请求，参考 {request} from 'ice'
	 */
	request?: any;
	/**
	 * 页面顶级参数，例如业务详情页面的业务appId将放在此属性中，供组件以及页面使用
	 */
	pageProps?: object;
}
/**
 * 属性面板属性
 */
export interface AttributesPanelProps {
	/**
	 * 模板数据
	 */
	templateData?: templateConfig;
	/**
	 * 画布的配置数据
	 */
	pageConfig?: pageConfig;
	/**
	 * 当前选中组件id
	 */
	selectId?: string;
	/**
	 * (pageConfig)=>void属性面板发生改变时的回调
	 */
	onChange?: (pageConfig: pageConfig) => void;
	/**
	 * 在开发npm包组件时需用到此属性。面板使用者无需使用此属性
	 */
	ExpCom?: React.ComponentClass;
	/**
	 * 应用框架级数据请求方法，用来实现数据请求，参考 {request} from 'ice'
	 */
	request?: any;
	/**
	 * 页面顶级参数，例如业务详情页面的业务appId将放在此属性中，供组件以及页面使用
	 */
	pageProps?: object;
	/**
	 * 属性面板配置数据
	 */
	attrConfig?: attrConfigItem[];
	/**
	 * 模板数据发生变更时回调
	 */
	onTemplateChange?: (templateData: templateConfig) => void;
	/**
	 * 无数据组件图片
	 */
	noDataImgSrc?: string;
	/**
	 * 布局选择组件依赖的图片路径
	 */
	imgPath?: string;
	/**
	 * 布局数据
	 */
	layoutList?: layoutListItem[];
	/**
	 * 透传tab组件属性
	 */
	tabProps?: object;
	/**
	 * 自定义导入组件类方法,请参考util.js中的getComRequire实现此方法
	 * (comName, importFrom)=>component Class
	 */
	customGetComRequire: (comName: string, importFrom: string) => React.ComponentClass;
}
/**
 * 页面生成器属性
 */
export interface PageCreaterProps {
	/**
	 * 只在组件demo中传入的组件class
	 */
	ExpCom?: React.ComponentClass;

	/**
	 * 组件列表数组，组件包名的域部分
	 * exp:@riil-frontend/component-page-creater -> [{type:"component-page-creater",importFrom:"npm"}]
	 * @default []
	 */
	comList?: comListItem[];
	/**
	 * 页面级公共参数部分，会透传给画布子组件pageProps
	 */
	pageProps?: object;
	/**
	 * request为ice框架数据请求的透传属性
	 * 具体使用方式请参考 {request} from 'ice'
	 */
	request?: any;
	/**
	 * 页面生成器配置数据
	 */
	pageConfig?: pageConfig;
	/**
	 * ResponsiveReactGridLayout组件属性
	 */
	layoutProps?: object;
	/**
	 * (path)=>void页面跳转操作
	 */
	jumpto?: (path: string) => void;
	/**
	 * 从列表添加组件、删除组件、修改属性面板、拖拽组件位置、修改组件大小触发回调
	 * (pageConfig)=>void
	 */
	onChange?: (pageConfig: pageConfig) => void;
}
