import * as R from "remeda";
import Victor from "@a-robu/victor";

import { readFile } from "../05/part1.js";

export const V = (...args) => new Victor(...args);
const parseLine = (line) => line.match(/[\d,]+/g).map((x) => eval(`[${x}]`));

const readInput = (...args) =>
  R.pipe(
    readFile(...args),
    (lines) => lines.split("\n"),
    R.compact, // remove last line
    R.map(parseLine)
  );

export const puzzleInput = readInput(import.meta.url, "input");
export const sample = readInput(import.meta.url, "sample");

export function genCave(rocks) {
  const cave = {};
  for (const rock of rocks) {
    const points = rock.map(Victor.fromArray);
    let from = points.shift();

    while (points.length) {
      /** @type Victor */
      const to = points.shift();
      const direction = to.clone().subtract(from).normalize();

      R.times(to.clone().subtract(from).length() + 1, () => {
        if (!cave[from.y]) cave[from.y] = {};
        cave[from.y][from.x] = "#";
        from.add(direction);
      });

      from = to;
    }
  }
  return cave;
}

function pourSand(cave) {
  cave = R.clone(cave);

  let sand = 0;

  /** @type Victor */
  let current;

  const maxDepth = R.pipe(
    cave,
    R.keys,
    R.map((x) => parseInt(x)),
    R.maxBy(R.identity)
  );

  console.log({ maxDepth });

  while (true) {
    if (!current) current = V(500, 0);
    if (current.y > maxDepth) return sand;

    const next = [
      [0, 1],
      [-1, 1],
      [1, 1],
    ]
      .map((args) => V(...args))
      .map((v) => v.add(current))
      .find((v) => !(cave[v.y] && cave[v.y][v.x]));
    if (next) {
      current = next;
    } else {
      if (!cave[current.y]) cave[current.y] = {};
      cave[current.y][current.x] = "o";
      sand++;
      current = null;
    }
  }
}

export default R.createPipe(genCave, pourSand);