import type { BoardNode, Port } from "./types";

export function portPoint(node: BoardNode, port: Port): { x: number; y: number } {
  const { x, y, w, h } = node;
  if (port === "n") return { x: x + w / 2, y };
  if (port === "s") return { x: x + w / 2, y: y + h };
  if (port === "w") return { x, y: y + h / 2 };
  return { x: x + w, y: y + h / 2 };
}

export function opposite(port: Port): Port {
  if (port === "n") return "s";
  if (port === "s") return "n";
  if (port === "w") return "e";
  return "w";
}

export function nearestPort(node: BoardNode, x: number, y: number): Port {
  const ports: Port[] = ["n", "s", "e", "w"];
  let best: Port = "e";
  let dist = Infinity;
  for (const p of ports) {
    const pt = portPoint(node, p);
    const d = (pt.x - x) ** 2 + (pt.y - y) ** 2;
    if (d < dist) {
      dist = d;
      best = p;
    }
  }
  return best;
}

export function edgePath(
  a: { x: number; y: number },
  b: { x: number; y: number },
  fromPort: Port,
  toPort: Port,
): string {
  const offset = (port: Port, p: { x: number; y: number }) => {
    const d = 48;
    if (port === "n") return { x: p.x, y: p.y - d };
    if (port === "s") return { x: p.x, y: p.y + d };
    if (port === "w") return { x: p.x - d, y: p.y };
    return { x: p.x + d, y: p.y };
  };
  const c1 = offset(fromPort, a);
  const c2 = offset(toPort, b);
  return `M ${a.x} ${a.y} C ${c1.x} ${c1.y}, ${c2.x} ${c2.y}, ${b.x} ${b.y}`;
}

export function hitNode(nodes: BoardNode[], x: number, y: number): BoardNode | null {
  for (let i = nodes.length - 1; i >= 0; i--) {
    const n = nodes[i]!;
    if (x >= n.x && x <= n.x + n.w && y >= n.y && y <= n.y + n.h) return n;
  }
  return null;
}

export function snap(n: number, grid = 8): number {
  return Math.round(n / grid) * grid;
}

export function clamp(n: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, n));
}

export function documentPath(w: number, h: number): string {
  const wave = Math.min(12, h * 0.18);
  return `M 0 0 H ${w} V ${h - wave} Q ${w * 0.75} ${h + wave} ${w / 2} ${h - wave} Q ${w * 0.25} ${h - 3 * wave} 0 ${h - wave} Z`;
}

export function diamondPoints(w: number, h: number): string {
  return `${w / 2},0 ${w},${h / 2} ${w / 2},${h} 0,${h / 2}`;
}

export function strokeHits(points: number[], x: number, y: number, radius: number): boolean {
  const r2 = radius * radius;
  for (let i = 0; i < points.length; i += 2) {
    const px = points[i]!;
    const py = points[i + 1]!;
    const dx = px - x;
    const dy = py - y;
    if (dx * dx + dy * dy <= r2) return true;
  }
  return false;
}

export const NODE_DEFAULTS: Record<string, { w: number; h: number; fill?: string }> = {
  sticky: { w: 180, h: 140, fill: "#fff8c5" },
  rect: { w: 180, h: 80 },
  ellipse: { w: 180, h: 80 },
  diamond: { w: 160, h: 120 },
  text: { w: 200, h: 36 },
  start: { w: 120, h: 56 },
  process: { w: 180, h: 72 },
  decision: { w: 160, h: 120 },
  document: { w: 180, h: 80 },
  taskcard: { w: 180, h: 80 },
};

export const STICKY_SWATCHES = ["#fff8c5", "#dafbe1", "#ddf4ff", "#ffebe9", "#ffffff"] as const;
