/**
 * @descriptin Api docs https://jbaysolutions.github.io/vue-grid-layout/zh/guide/properties.html#griditem
 */
declare module 'vue3-grid-layout' {
  import type { CSSProperties } from 'vue';

  interface Layout {
    i: string;
    x: number;
    y: number;
    w: number;
    h: number;
    static?: boolean;
  }

  interface BreakPoints {
    lg?: number;
    md?: number;
    sm?: number;
    xs?: number;
    xxs?: number;
  }

  interface GridLayoutProps {
    layout: Layout[];

    responsiveLayouts?: any;

    /**
     * @description Define Col Number, Need A Integer Number
     * @type number
     * @default 12
     */
    colNum?: number;

    /**
     * @description Define Row Height
     * @type number
     * @default 150
     */
    rowHeight?: number;

    /**
     * @description Define Max Rows
     * @type number
     * @default infinity
     */
    maxRows?: number;

    /**
     * @description Define Marign Distance In Grid Layout
     * @type [number, number]
     * @default [10, 10]
     */
    margin?: [number, number];

    /**
     * @description Define Element Can Draggable In Grid Layout
     * @type boolean
     * @default true
     */
    isDraggable?: boolean;

    /**
     * @description Define Element Can Resizeable In Grid Layout
     * @type boolean
     * @default true
     */
    isResizable?: boolean;

    /**
     * @description Define Element Can Mirrored In Grid Layout
     * @type boolean
     * @default false
     */
    isMirrored?: boolean;

    /**
     * @descripion Define Element Can Auto Size In Grid Layout
     * @type boolean
     * @default true
     */
    autoSize?: boolean;

    /**
     * @description Define Element Can Compact On Vertical Direction
     * @type boolean
     * @default false
     */
    verticalCompact?: boolean;

    /**
     * @description Define Element Prevent Collision
     * @type {boolean}
     * @default false
     */
    preventCollision?: boolean;

    /**
     * @description Define Element Use Css Transforms
     * @type {boolean}
     * @default true
     */
    useCssTransforms?: boolean;

    /**
     * @description Define Whether Is Responsive Layout
     * @type {boolean}
     * @default false
     */
    responsive?: boolean;

    /**
     * @description Setting Screen Break Points
     * @type {BreakPoints}
     * @default lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0
     */
    breakPoints?: BreakPoints;

    /**
     * @description Setting Column Break Points
     * @type {BreakPoints}
     * @default  lg: 12, md: 10, sm: 6, xs: 4, xxs: 2
     */
    cols?: BreakPoints;

    /**
     * @descritpion Use Dynamic Cursor Style
     * @type {boolean}
     * @default false
     * @deprecated
     */
    useStyleCursor?: boolean;

    [key: string]: any;
  }

  interface GridItemProps extends Layout {
    /**
     * @description Min Width
     * @type {number}
     * @default 1
     */
    minW?: number;

    /**
     * @description Min Height
     * @type {number}
     * @default 1
     */
    minH?: number;

    /**
     * @description Max Width
     * @type {number}
     * @default 1
     */
    maxW?: number;

    /**
     * @description Min Height
     * @type {number}
     * @default 1
     */
    maxH?: number;

    /**
     * @description Flag Grid Element Can Draggable
     * @type {boolean | null}
     * @default null
     */
    isDraggable?: boolean;

    /**
     * @descrition Flag Grid Element Can Resizeable
     * @type {boolean | null}
     * @default null
     */
    isResizeable?: boolean;

    /**
     * @description Flag Grid Element Is Static , Can't Draggable Resizeable Move
     * @type {boolean}
     * @default false
     */
    static?: boolean;

    /**
     * @description Flag What Are The Element Can't Draggable, Usage Css Picker
     * @type {string}
     * @default 'a button'
     */
    dragIgnoreFrom?: string;

    /**
     * @description Flag What Are The Element Allow Draggable, Usage Css Picker
     * @type {string}
     * @default null
     */
    dragAllowFrom?: string;

    /**
     * @description Flag What Are The Element Can't Trigger Resize, Usage Css Picker
     * @type {string}
     * @deafult 'a button'
     */
    resizeIgnoreFrom?: string;

    style?: CSSProperties;

    onLayoutCreate?: (newLayout: Layout[]) => void;

    [key: string]: any;
  }
  type GirdLayoutEvent =
    | 'layoutCreate'
    | 'layoutBeforeMount'
    | 'layoutMounted'
    | 'layoutReady'
    | 'layoutUpdate'
    | 'breakpointChanged';

  interface LayoutBaseParams {
    newLayout: Layout[];
  }

  interface GridLayoutEmit {
    layoutCreate: LayoutBaseParams;
    layoutBeforeMount: LayoutBeforeMountParams;
    layoutMounted: LayoutMountedParams;
    layoutReady: layoutUpdateParams;
    layoutUpdate: layoutUpdateParams;
    breakpointChanged: breakpointChangedParams;
  }

  /**
   * @description Grid Item Event Name
   */
  type GridItemEvent = 'move' | 'moved' | 'resize' | 'resized' | 'containerResized';

  interface MoveParams {
    i: number;
    newX?: number;
    newY?: number;
  }

  interface ResizeParams {
    i: number;
    newH: number;
    newW: number;
    newHPx: number;
    newWPx: number;
  }

  interface GridItemEmit {
    move: MoveParams;
    moved: MoveParams;
    resize: ResizeParams;
    resized: ResizeParams;
    containerResized: MoveParams;
  }

  // const GridLayout: DefineComponent<GridLayoutProps, void, unknown>
  // const GridItem: DefineComponent<GridItemProps, void, unknown>

  const GridLayout: {
    new (): {
      $props: GridLayoutProps;
      $emit: <T extends GirdLayoutEvent>(event: T, ...args: GridLayoutEmit[T]) => void;
    };
  };

  const GridItem: {
    new (): {
      $props: GridItemProps;
      $emit: <T extends GridItemEvent>(event: T, ...args: GridItemEmit[T]) => void;
    };
  };

  export { GridLayout, GridItem, BreakPoints, Layout, LayoutBaseParams, ResizeParams };
}
