import {
  IModuleCallbacksMap,
  IModuleMutableProps,
  IModuleStaticProps,
} from '@/base/Module';

import { CursorHoverElement } from './HoverElement';

export interface ICursorStaticProps extends IModuleStaticProps {
  /**
   * The container where the custom cursor is active.
   * Use `window` for full-window activation.
   * @default window
   */
  container?: Element | Window;

  /**
   * Hides the native cursor if set to `true`.
   * @default false
   */
  hideNative?: boolean;

  /**
   * Appends the custom cursor to the container. Use `false` if you need only cursor logic and interactions.
   * @default true
   */
  append?: boolean;

  /**
   * Cursor behavior
   * @default 'default'
   */
  behavior?: 'default' | 'path';

  /**
   * Modifier for the cursor transform.
   * @default (coords) => `translate(${coords.x}px, ${coords.y}px)`
   */
  transformModifier?: (coords: ICursorFullCoords) => string;
}

export interface ICursorMutableProps extends IModuleMutableProps {
  /**
   * Enables or disables the custom cursor interactions.
   * @default true
   */
  enabled?: boolean;

  /**
   * The initial width of the custom cursor.
   * Supports css units like `px`, `rem`, `vw`, `vh`, `svh`.
   * @default 50
   */
  width?: number | string;

  /**
   * The initial height of the custom cursor.
   * Supports css units like `px`, `rem`, `vw`, `vh`, `svh`.
   * @default 50
   */
  height?: number | string;

  /**
   * Linear interpolation factor for smooth cursor movement.
   * The value must be between `0` and `1`, with higher values indicating faster movement.
   * @default 0.2
   */
  lerp?: number;

  /**
   * Stops rendering the cursor automatically when its coordinates and size
   * closely match the target values.
   * @default true
   */
  autoStop?: boolean;
}

/**
 * Callback types for the custom cursor component.
 */
export interface ICursorCallbacksMap extends IModuleCallbacksMap<ICursorMutableProps> {
  /**
   * Triggered on each render to update the cursor's position.
   */
  render: undefined;

  /**
   * Triggered when an attached element is hovered.
   */
  hoverEnter: CursorHoverElement;

  /**
   * Triggered when an attached element is no longer hovered.
   */
  hoverLeave: CursorHoverElement;

  /**
   * Triggered when a cursor type is visible.
   */
  typeShow: ICursorType;

  /**
   * Triggered when a cursor type becomes invisible.
   */
  typeHide: ICursorType;

  /**
   * Triggered when no cursor type is applied.
   */
  noType: undefined;
}

/**
 * Represents the cursor's target position, angle and velocity.
 */
export interface ICursorTargetCoords {
  x: number;
  y: number;
  angle: number;
  velocity: number;
}

/**
 * Represents the cursor's coordinates, angle and size.
 */
export interface ICursorFullCoords extends ICursorTargetCoords {
  width: number;
  height: number;
}

/**
 * Custom cursor type configuration.
 */
export interface ICursorType {
  /** Custom cursor element */
  element: Element;

  /** Cursor type */
  type: string;
}
