import { useState, useEffect } from "react";
import { useLocalStorage } from "../../useLocalStorage";

const TYPE_VIN = "vin";

/**
 * Match VIN with RegEx
 * @param {string} vin - potential VIN
 * @returns {[boolean, string]}
 */
function parseVin(vin = "") {
  const prefix = new RegExp(`^${TYPE_VIN}:`);
  if (vin.match(prefix)) {
    return [true, vin.replace(prefix, "")];
  }

  vin = vin.replace(/[^\p{L}\d]/gu, '');

  var re = new RegExp("^[A-HJ-NPR-Z0-9]{8}[0-9X][A-HJ-NPR-Z0-9]{2}[0-9]{6}$");
  return [vin.match(re), vin];
}

/**
 * Convert a string into a QueryPart tuple.
 * @typedef {"search" | "vin"} Type - the type of value represented
 * @typedef {string} Value - the value
 * @typedef {[Type, Value]} QueryPart - a tuple representing a substring of a query
 * @param {string} part - substring of a query to turn into a QueryPart
 * @returns {QueryPart}
 */
function parseQueryPart(part) {
  let type = "search";

  const [isVin, vin] = parseVin(part)
  if (isVin) {
    type = TYPE_VIN;
    part = vin;
  }

  return [type, part];
}

export default function useQuery() {
  const [query, setQuery] = useLocalStorage("VEHICLE_SEARCH", "");
  const [parts, setParts] = useState([]);
  const [payload, setPayload] = useState({});
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    let vins = [];
    let search = "";
    const parts = query.replaceAll(" ", ",").split(",").map(parseQueryPart);
    setParts(parts);

    parts.forEach(([type, value]) => {
      if (type === "vin") {
        vins.push(value);
      }

      if (type === "search") {
        search = `${search} ${value}`.trim();
      }
    });

    setQuery(() => parts.map(([type, part]) => {
      if (type !== "search") {
        return `${type}:${part}`;
      }

      return part;
    }).join(" ").replace(/\s{2,}/g, ' ').trim());

    setPayload({
      search,
      vins: vins.join(","),
    })
  }, [query, setPayload, setQuery]);

  useEffect(() => {
    setLoading(false);
  }, [payload, setLoading])

  return {
    parts,
    payload,
    query,
    setQuery,
    loading,
  }
}
