import React from 'react';
import { afterEach, vi } from 'vitest';
import { cleanup } from '@testing-library/react';
import '@testing-library/jest-dom/vitest';

afterEach(() => {
  cleanup();
  localStorage.clear();
});

vi.stubGlobal('alert', vi.fn());
vi.stubGlobal('confirm', vi.fn(() => true));
URL.createObjectURL = vi.fn(() => 'blob:mock-url');
URL.revokeObjectURL = vi.fn();
HTMLAnchorElement.prototype.click = vi.fn();

function makeStageEvent(x = 120, y = 80) {
  const stage = {
    getPointerPosition: () => ({ x, y }),
    getRelativePointerPosition: () => ({ x, y }),
    scaleX: () => 1,
    x: () => 0,
    y: () => 0,
  };

  return {
    evt: { preventDefault: vi.fn(), deltaY: -1 },
    target: {
      getStage: () => stage,
    },
  };
}

vi.mock('react-konva', () => ({
  Stage: ({ children, onClick, onMouseDown, onMouseUp, onMouseMove, onWheel }: any) => {
    const coords = (event: React.MouseEvent<HTMLDivElement>, fallbackX: number, fallbackY: number) => ({
      x: event.clientX || fallbackX,
      y: event.clientY || fallbackY,
    });
    return (
    <div
      data-testid="konva-stage"
      onClick={(event) => {
        const point = coords(event, 120, 80);
        onClick?.(makeStageEvent(point.x, point.y));
      }}
      onMouseDown={(event) => {
        const point = coords(event, 120, 80);
        onMouseDown?.(makeStageEvent(point.x, point.y));
      }}
      onMouseUp={(event) => {
        const point = coords(event, 260, 200);
        onMouseUp?.(makeStageEvent(point.x, point.y));
      }}
      onMouseMove={(event) => {
        const point = coords(event, 180, 120);
        onMouseMove?.(makeStageEvent(point.x, point.y));
      }}
      onWheel={() => onWheel?.(makeStageEvent())}
    >
      {children}
    </div>
    );
  },
  Layer: ({ children }: any) => <div data-testid="konva-layer">{children}</div>,
  Group: ({ children, opacity }: any) => <div data-testid="konva-group" data-opacity={opacity}>{children}</div>,
  Image: ({ image }: any) => <img data-testid="konva-image" alt="" src={image?.src || ''} />,
  Circle: (props: any) => (
    <span
      data-testid="konva-circle"
      data-fill={props.fill}
      data-x={props.x}
      data-y={props.y}
      onClick={(event) => {
        const point = {
          x: event.clientX || 120,
          y: event.clientY || 80,
        };
        const konvaEvent = { ...makeStageEvent(point.x, point.y), cancelBubble: false };
        props.onClick?.(konvaEvent);
        if (konvaEvent.cancelBubble) event.stopPropagation();
      }}
      onMouseDown={(event) => {
        const point = {
          x: event.clientX || props.x || 120,
          y: event.clientY || props.y || 80,
        };
        const konvaEvent = { ...makeStageEvent(point.x, point.y), cancelBubble: false };
        props.onMouseDown?.(konvaEvent);
        props.onDragStart?.(konvaEvent);
        if (konvaEvent.cancelBubble) event.stopPropagation();
      }}
      onMouseMove={(event) => props.onDragMove?.({
        target: {
          x: () => event.clientX || props.x || 0,
          y: () => event.clientY || props.y || 0,
        },
      })}
      onMouseUp={(event: React.MouseEvent<HTMLSpanElement>) => props.onDragEnd?.({
        target: {
          x: () => event.clientX || props.x || 0,
          y: () => event.clientY || props.y || 0,
        },
      })}
      onDragEnd={(event: React.DragEvent<HTMLSpanElement>) => props.onDragEnd?.({
        target: {
          x: () => event.clientX || props.x || 0,
          y: () => event.clientY || props.y || 0,
        },
      })}
    />
  ),
  Rect: (props: any) => <span data-testid="konva-rect" data-width={props.width} />,
  Path: (props: any) => (
    <span
      data-testid="konva-path"
      data-path={props.data}
      data-fill={props.fill}
      data-stroke={props.stroke}
      data-stroke-width={props.strokeWidth}
      data-dash={props.dash?.join(',') || ''}
      data-fill-rule={props.fillRule}
      onClick={(event) => {
        const point = {
          x: event.clientX || 120,
          y: event.clientY || 80,
        };
        const konvaEvent = { ...makeStageEvent(point.x, point.y), cancelBubble: false };
        props.onClick?.(konvaEvent);
        if (konvaEvent.cancelBubble) event.stopPropagation();
      }}
      onDoubleClick={(event) => {
        const point = {
          x: event.clientX || 120,
          y: event.clientY || 80,
        };
        const konvaEvent = { ...makeStageEvent(point.x, point.y), cancelBubble: false };
        props.onDblClick?.(konvaEvent);
        if (konvaEvent.cancelBubble) event.stopPropagation();
      }}
    />
  ),
}));

vi.mock('use-image', () => ({
  default: (src: string) => [
    {
      src,
      width: 640,
      height: 360,
      naturalWidth: 640,
      naturalHeight: 360,
    },
    'loaded',
  ],
}));
