import type { EditorObject } from "../store/editorStore.types";

export type CustomShapePointBounds = {
  minX: number;
  minY: number;
  width: number;
  height: number;
};

export const getCustomShapePointBounds = (
  points: number[],
): CustomShapePointBounds => {
  const xs = points.filter((_, i) => i % 2 === 0);
  const ys = points.filter((_, i) => i % 2 !== 0);

  if (xs.length === 0 || ys.length === 0) {
    return { minX: 0, minY: 0, width: 100, height: 100 };
  }

  const minX = Math.min(...xs);
  const minY = Math.min(...ys);
  const maxX = Math.max(...xs);
  const maxY = Math.max(...ys);

  return {
    minX,
    minY,
    width: Math.max(1, maxX - minX),
    height: Math.max(1, maxY - minY),
  };
};

/**
 * Ensures custom-shape points start at (0,0), width/height match the polygon,
 * and opacity uses the editor's 0–100 scale (not Konva's 0–1).
 */
export const normalizeCustomShapeObject = (
  obj: EditorObject,
): EditorObject => {
  if (obj.type !== "custom-shape" || !obj.points || obj.points.length < 6) {
    return obj;
  }

  let next: EditorObject = { ...obj };

  if (
    next.opacity !== undefined &&
    next.opacity > 0 &&
    next.opacity <= 1
  ) {
    next = { ...next, opacity: next.opacity * 100 };
  }

  const points = next.points!;
  const { minX, minY, width, height } = getCustomShapePointBounds(points);

  if (minX !== 0 || minY !== 0) {
    next = {
      ...next,
      x: (next.x ?? 0) + minX,
      y: (next.y ?? 0) + minY,
      width,
      height,
      points: points.map((val, i) =>
        i % 2 === 0 ? val - minX : val - minY,
      ),
    };
  } else if (next.width !== width || next.height !== height) {
    next = { ...next, width, height };
  }

  return next;
};

const MIN_PENCIL_POINTS = 4;

/**
 * Ensures pencil stroke points are relative to obj.x/obj.y and bbox matches width/height.
 */
export const normalizePencilObject = (obj: EditorObject): EditorObject => {
  if (obj.type !== "pencil" || !obj.points || obj.points.length < MIN_PENCIL_POINTS) {
    return obj;
  }

  let next: EditorObject = { ...obj, closed: false };

  if (
    next.opacity !== undefined &&
    next.opacity > 0 &&
    next.opacity <= 1
  ) {
    next = { ...next, opacity: next.opacity * 100 };
  }

  const points = next.points!;
  const { minX, minY, width, height } = getCustomShapePointBounds(points);

  if (minX !== 0 || minY !== 0) {
    next = {
      ...next,
      x: (next.x ?? 0) + minX,
      y: (next.y ?? 0) + minY,
      width,
      height,
      points: points.map((val, i) =>
        i % 2 === 0 ? val - minX : val - minY,
      ),
    };
  } else if (next.width !== width || next.height !== height) {
    next = { ...next, width, height };
  }

  return next;
};
