import { TLUiOverrides } from "tldraw"
import {
  cameraHistory,
  copyLinkToCurrentView,
  lockCameraToFrame,
  revertCamera,
  zoomToSelection,
} from "./cameraUtils"
import { saveToPdf } from "../utils/pdfUtils"

export const overrides: TLUiOverrides = {
  tools(editor, tools) {
    return {
      ...tools,
      select: {
        ...tools.select,
        onPointerDown: (info: any) => {
          const shape = editor.getShapeAtPoint(info.point)
          if (shape && editor.getSelectedShapeIds().includes(shape.id)) {
            // If clicking on a selected shape, initiate drag behavior
            editor.dispatch({
              type: "pointer",
              name: "pointer_down",
              point: info.point,
              button: info.button,
              shiftKey: info.shiftKey,
              altKey: info.altKey,
              ctrlKey: info.ctrlKey,
              metaKey: info.metaKey,
              pointerId: info.pointerId,
              target: "shape",
              shape,
              isPen: false,
              accelKey: info.ctrlKey || info.metaKey,
            })
            return
          }
          // Otherwise, use default select tool behavior
          ;(tools.select as any).onPointerDown?.(info)
        },
      },
      VideoChat: {
        id: "VideoChat",
        icon: "video",
        label: "Video Chat",
        kbd: "alt+v",
        readonlyOk: true,
        onSelect: () => editor.setCurrentTool("VideoChat"),
      },
      ChatBox: {
        id: "ChatBox",
        icon: "chat",
        label: "Chat",
        kbd: "alt+c",
        readonlyOk: true,
        onSelect: () => editor.setCurrentTool("ChatBox"),
      },
      Embed: {
        id: "Embed",
        icon: "embed",
        label: "Embed",
        kbd: "alt+e",
        readonlyOk: true,
        onSelect: () => editor.setCurrentTool("Embed"),
      },
      // Markdown: {
      //   id: "Markdown",
      //   icon: "markdown",
      //   label: "Markdown",
      //   kbd: "alt+m",
      //   readonlyOk: true,
      //   onSelect: () => editor.setCurrentTool("Markdown"),
      // },
    }
  },
  actions(editor, actions) {
    return {
      ...actions,
      zoomToSelection: {
        id: "zoom-to-selection",
        label: "Zoom to Selection",
        kbd: "z",
        onSelect: () => {
          if (editor.getSelectedShapeIds().length > 0) {
            zoomToSelection(editor)
          }
        },
        readonlyOk: true,
      },
      copyLinkToCurrentView: {
        id: "copy-link-to-current-view",
        label: "Copy Link to Current View",
        kbd: "alt+c",
        onSelect: () => {
          copyLinkToCurrentView(editor)
        },
        readonlyOk: true,
      },
      revertCamera: {
        id: "revert-camera",
        label: "Revert Camera",
        kbd: "alt+b",
        onSelect: () => {
          if (cameraHistory.length > 0) {
            revertCamera(editor)
          }
        },
        readonlyOk: true,
      },
      lockToFrame: {
        id: "lock-to-frame",
        label: "Lock to Frame",
        kbd: "shift+l",
        onSelect: () => lockCameraToFrame(editor),
      },
      saveToPdf: {
        id: "save-to-pdf",
        label: "Save Selection as PDF",
        kbd: "alt+p",
        onSelect: () => {
          if (editor.getSelectedShapeIds().length > 0) {
            saveToPdf(editor)
          }
        },
        readonlyOk: true,
      },
      // TODO: FIX THIS
      handleSelectedShapeDrag: {
        id: "handle-selected-shape-drag",
        label: "Drag Selected Shape",
        onSelect: (info: any) => {
          const shape = editor.getShapeAtPoint(info.point)
          if (shape && editor.getSelectedShapeIds().includes(shape.id)) {
            if (editor.isPointInShape(shape, info.point)) {
              editor.dispatch({
                type: "pointer",
                name: "pointer_down",
                point: info.point,
                button: info.button,
                shiftKey: info.shiftKey,
                altKey: info.altKey,
                ctrlKey: info.ctrlKey,
                metaKey: info.metaKey,
                accelKey: info.ctrlKey || info.metaKey,
                pointerId: info.pointerId,
                target: "shape",
                shape,
                isPen: false,
              })
            }
          }
        },
      },
      moveSelectedLeft: {
        id: "move-selected-left",
        label: "Move Left",
        kbd: "ArrowLeft",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                x: shape.x - 50,
                y: shape.y,
              })
            })
          }
        },
      },
      moveSelectedRight: {
        id: "move-selected-right",
        label: "Move Right",
        kbd: "ArrowRight",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                x: shape.x + 50,
                y: shape.y,
              })
            })
          }
        },
      },
      moveSelectedUp: {
        id: "move-selected-up",
        label: "Move Up",
        kbd: "ArrowUp",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                x: shape.x,
                y: shape.y - 50,
              })
            })
          }
        },
      },
      moveSelectedDown: {
        id: "move-selected-down",
        label: "Move Down",
        kbd: "ArrowDown",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                x: shape.x,
                y: shape.y + 50,
              })
            })
          }
        },
      },

      // TODO: FIX THIS
      resizeSelectedUp: {
        id: "resize-selected-up",
        label: "Resize Up",
        kbd: "ctrl+ArrowUp",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              const bounds = editor.getShapeGeometry(shape).bounds
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                //y: shape.y - 50,
                props: {
                  ...shape.props,
                  h: bounds.height + 50,
                },
              })
            })
          }
        },
      },
      resizeSelectedDown: {
        id: "resize-selected-down",
        label: "Resize Down",
        kbd: "ctrl+ArrowDown",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              const bounds = editor.getShapeGeometry(shape).bounds
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                props: {
                  ...shape.props,
                  h: bounds.height + 50,
                },
              })
            })
          }
        },
      },
      resizeSelectedLeft: {
        id: "resize-selected-left",
        label: "Resize Left",
        kbd: "ctrl+ArrowLeft",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              const bounds = editor.getShapeGeometry(shape).bounds
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                props: {
                  ...shape.props,
                  w: bounds.width + 50,
                },
              })
            })
          }
        },
      },
      resizeSelectedRight: {
        id: "resize-selected-right",
        label: "Resize Right",
        kbd: "ctrl+ArrowRight",
        onSelect: () => {
          const selectedShapes = editor.getSelectedShapes()
          if (selectedShapes.length > 0) {
            selectedShapes.forEach((shape) => {
              const bounds = editor.getShapeGeometry(shape).bounds
              editor.updateShape({
                id: shape.id,
                type: shape.type,
                props: {
                  ...shape.props,
                  w: bounds.width + 50,
                },
              })
            })
          }
        },
      },
      //TODO: MAKE THIS WORK, ADD USER PERMISSIONING TO JOIN BROADCAST?
      broadcastView: {
        id: "broadcast-view",
        label: "Broadcast View",
        kbd: "alt+b",
        readonlyOk: true,
        onSelect: () => {
          const collaborators = editor.getCollaborators()
          collaborators
            .filter((user) => user.id !== editor.user.getId())
            .forEach((user) => {
              editor.startFollowingUser(user.id)
            })
        },
      },
      stopBroadcast: {
        id: "stop-broadcast",
        label: "Stop Broadcasting",
        kbd: "alt+shift+b",
        readonlyOk: true,
        onSelect: () => {
          editor.stopFollowingUser()
        },
      },
    }
  },
}
