declare module '*.svg' {
  const content: string;
  export default content;
}

declare module 'pdfjs-dist/es5/build/pdf.js';
declare module 'query-string';
declare module 'react-color';
declare module 'react-color/lib/components/common';
declare module 'react-toast-notifications';

interface RefObject<T> {
  readonly current: T | null;
}

type SelectOptionType = {
  key: string | number;
  content: React.ReactNode;
  child: React.ReactNode;
};

type RenderingStateType = 'RENDERING' | 'LOADING' | 'FINISHED' | 'PAUSED';

enum FormType {
  textfield = 'textfield',
  checkbox = 'checkbox',
  radio = 'radio',
}

enum ToolType {
  highlight = 'highlight',
  freehand = 'freehand',
  text = 'text',
  sticky = 'sticky',
  shape = 'shape',
}

enum SidebarType {
  'markup-tools' = 'markup-tools',
  'create-form' = 'create-form',
  watermark = 'watermark',
  image = 'image',
}

type ViewportType = {
  width: number;
  height: number;
};

type ProgressType = {
  loaded: number;
  total: number;
};

type ScrollStateType = {
  right: boolean;
  down: boolean;
  lastX: number;
  lastY: number;
  subscriber: Subscription;
};

type PositionType = {
  top: number;
  bottom: number;
  left: number;
  right: number;
};

type HTMLCoordinateType = {
  top: number;
  left: number;
  width: number;
  height: number;
};

type PointType = {
  x: number;
  y: number;
};

type LinePositionType = {
  start: PointType;
  end: PointType;
};

type AnnotationPositionType =
  | PositionType
  | LinePositionType
  | PointType
  | (PositionType | PointType[])[];

type AnnotationAttributeType = {
  title?: string;
  date?: string;
  page: number;
  bdcolor?: string | undefined;
  position?: AnnotationPositionType;
  transparency?: number | undefined;
  content?: string | undefined;
  style?: string | undefined;
  fcolor?: string | undefined;
  ftransparency?: number | undefined;
  bdwidth?: number | undefined;
  fontname?: string | undefined;
  fontsize?: number | undefined;
  textcolor?: string | undefined;
  is_arrow?: boolean | undefined;
  src?: string | undefined;
};

type AnnotationType = {
  id?: string;
  obj_type: string;
  obj_attr: AnnotationAttributeType;
};

type UpdateData = {
  bdcolor?: string;
  transparency?: number;
  position?: AnnotationPositionType;
  content?: string;
  fontsize?: number;
};

type OnUpdateType = (data: UpdateData) => void;

type AnnotationElementPropsType = AnnotationType & {
  isCovered: boolean;
  isCollapse: boolean;
  mousePosition: Record<string, unknown>;
  onUpdate: OnUpdateType;
  onDelete: () => void;
  scale: number;
  viewport: ViewportType;
  onEdit: () => void;
  isEdit: boolean;
  onBlur: () => void;
  onMouseOver?: () => void;
  onMouseOut?: () => void;
};

type OptionPropsType = {
  type?: string;
  color?: string;
  opacity?: number;
  fontName?: string;
  fontSize?: number;
  width?: number;
  align?: string;
  fontStyle?: string;
  shape?: string;
  text?: string;
  setDataState?: (arg: Record<string, unknown>) => void;
};

type CoordType = {
  left: number;
  top: number;
  width?: number;
  height?: number;
};

type CircleType = {
  direction: string;
  cx: number;
  cy: number;
  r: number;
};

type WatermarkType = {
  type?: 'image' | 'text';
  scale?: number;
  opacity?: number;
  rotation?: number;
  pages?: string;
  vertalign?: 'top' | 'center' | 'bottom';
  horizalign?: 'left' | 'center' | 'right';
  xoffset?: number;
  yoffset?: number;
  imagepath?: string;
  text?: string;
  textcolor?: string;
  isfront?: 'yes' | 'no';
};

type MatchType = {
  page: number;
  index: number;
};

type ColorType = {
  h?: string;
  s?: string;
  l?: string;
  v?: string;
  a?: string;
  hex?: string;
};

type PdfType = {
  getPage: (number) => Promise<PdfPageType>;
  numPages: number;
} | null;

type GetPageType = () => Promise<PdfPageType>;

type TextItem = {
  items: unknown[];
};

type PdfPageType = {
  getTextContent: ({ normalizeWhitespace: boolean }) => Promise<TextItemp>;
  getViewport: (any) => ViewportType;
  cleanup: () => void;
  render: ({ canvasContext: any, viewport: any }) => RenderTaskType;
} | null;

type RenderTaskType = {
  cancel: () => void;
  promise: {
    catch: (arg0: (reason: sting) => void) => string;
  };
};

type ElementAttributeType = {
  title: Attr;
  date: Attr;
  page: Attr;
  color: Attr;
  width: Attr;
  opacity: Attr;
  'interior-color': Attr;
  'interior-opacity': Attr;
  tail: Attr;
  style: Attr;
  start: Attr;
  end: Attr;
  rect: Attr;
  coords: Attr;
} & NamedNodeMap;

type DispatchObjType = {
  type: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  payload: any;
};

type DispatchType = ({ type, payload }: DispatchObjType) => void;

type ActionType = (
  dispatch: DispatchType,
) => Record<string, (arg0?: unknown, arg1?: unknown) => void>;

type ReducerFuncType = (
  state: MainStateType & PdfStateType & SearchStateType,
  action: DispatchObjType,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
) => any;

type MainStateType = {
  displayMode: 'full' | 'normal';
  navbarState: 'search' | 'annotations' | 'thumbnails' | '';
  sidebarState: SidebarType | '';
  toolState: ToolType | FormType | '';
  info: { token: string; id: string };
  initiated: boolean;
  isLoading: boolean;
};

type PdfStateType = {
  totalPage: number;
  currentPage: number;
  pdf: PdfType;
  progress: ProgressType;
  viewport: ViewportType;
  scale: number;
  rotation: number;
  annotations: AnnotationType[];
  watermark: WatermarkType;
};

type SearchStateType = {
  queryString: string;
  currentIndex: number;
  matchesMap: MatchType[];
};
