import { defaultShadeOption, defaultShadeFactorsSet, TYPE } from "../constants";
import { generateShades, mergeObjects } from "../utils";
import type { ShadeOption, ShadesSet, ShadeFactorsSet, UseThemerProp } from "../types";
import useValidate from "./useValidate";

/**
 * **shadeOptions**
 * - colour input from user to generate theme
 * - user's input is validated first, if errors, return error and stop
 * - if no errors, merge with default options
 * - apply options to generate theme
 *
 * **shadeFactorsSets**
 * - if user provides custom shades, validate first
 * - if no errors, merge with default shades
 * - apply shades to generate theme
 *
 * @param InputObject
 * @returns
 */
export default function useThemer(props: UseThemerProp) {
  const { shadeOptions, shadeFactorsSets } = props;

  console.log("shadeOptions", shadeOptions);

  let output = {
    shadesSet: null,
    shadeOptions: null,
    shadeFactorsSets: null,
    errors: {},
  };

  const { result: validatedShadeOptions, errors: optionsErrors } = useValidate(shadeOptions);

  console.log("optionsErrors", optionsErrors);

  if (optionsErrors) return { ...output, errors: optionsErrors };

  console.log("validatedShadeOptions", validatedShadeOptions);

  // if no custom options, use default options
  const mergedShadeOptions: ShadeOption[] = [];

  const nextPush: ShadeOption | undefined = shadeOptions
    ? mergeObjects<ShadeOption>(defaultShadeOption, validatedShadeOptions)
    : defaultShadeOption;

  console.log("nextPush", nextPush);

  mergedShadeOptions.push(nextPush!);

  // if no custom shades, use default shades
  const mergedShadeFactorsSet = shadeFactorsSets
    ? mergeObjects<ShadeFactorsSet>(defaultShadeFactorsSet, shadeFactorsSets)
    : defaultShadeFactorsSet;

  console.log("mergedShadeOptions", mergedShadeOptions);
  console.log("mergedShadeFactorsSet", mergedShadeFactorsSet);

  // begin theme generation
  const shadesSets: ShadesSet[] = [];

  mergedShadeOptions.forEach((option) => {
    if (!option.generateShades) {
      shadesSets.push({
        type: TYPE.SHADES_SET,
        setName: option.optionName,
        shades: {
          normal: option.hex,
        },
      });
      return;
    }

    shadesSets.push({
      type: TYPE.SHADES_SET,
      setName: option.optionName,
      shades: generateShades(option, mergedShadeFactorsSet),
    });
  });

  return {
    ...output,
    shadeOptions: mergedShadeOptions,
    shadeFactorsSets: mergedShadeFactorsSet,
    shadesSets,
  };
}
