/** Drag-and-drop MIME + helpers for reordering sidebar labels / folders. */

export const SIDEBAR_NAV_DND_MIME = "application/x-ultimail-sidebar-nav"

export type SidebarNavDragPayload =
  | { kind: "label"; id: string }
  | { kind: "folder"; id: string }

export type SidebarNavDropPlacement = "before" | "after" | "inside"

export function setSidebarNavDragData(
  e: React.DragEvent,
  payload: SidebarNavDragPayload
) {
  const encoded = JSON.stringify(payload)
  e.dataTransfer.setData(SIDEBAR_NAV_DND_MIME, encoded)
  /** Fallback for browsers that hide custom types until drop. */
  e.dataTransfer.setData("text/plain", encoded)
  e.dataTransfer.effectAllowed = "move"
}

export function readSidebarNavDragData(
  e: React.DragEvent,
  active: SidebarNavDragPayload | null = null
): SidebarNavDragPayload | null {
  for (const mime of [SIDEBAR_NAV_DND_MIME, "text/plain"]) {
    const raw = e.dataTransfer.getData(mime)
    if (!raw) continue
    try {
      const parsed = JSON.parse(raw) as SidebarNavDragPayload
      if (parsed?.kind === "label" || parsed?.kind === "folder") {
        if (typeof parsed.id === "string" && parsed.id.length > 0) return parsed
      }
    } catch {
      /* ignore */
    }
  }
  return active
}

export function hasSidebarNavDrag(e: React.DragEvent): boolean {
  return e.dataTransfer.types.includes(SIDEBAR_NAV_DND_MIME)
}

/** Prefer React state — `dataTransfer.types` is unreliable during `dragover`. */
export function isSidebarNavDragEvent(
  e: React.DragEvent,
  active: SidebarNavDragPayload | null
): boolean {
  return active !== null || hasSidebarNavDrag(e)
}

/** Top/bottom thirds = reorder; middle third = nest (folders only). */
export function resolveNavDropPlacement(
  e: React.DragEvent<Element>,
  allowNest: boolean
): SidebarNavDropPlacement {
  const rect = e.currentTarget.getBoundingClientRect()
  const ratio = (e.clientY - rect.top) / Math.max(rect.height, 1)
  if (!allowNest) return ratio < 0.5 ? "before" : "after"
  if (ratio < 0.25) return "before"
  if (ratio > 0.75) return "after"
  return "inside"
}
