import { useEditor } from "@/modules/editor";
import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
import { Background, Layout } from "@/modules/editor/typings";
import { cloneDeep, defaultsDeep } from "lodash";
import { AnyFun } from "queenjs/typing";
import { addCacheToMap } from "./createCompId";

type IOptions<T, C> = {
  value: T;
  layout?: Layout;
  background?: Background;
  children?: C;
};

export function createCompHooks<T, C extends { [name: string]: AnyFun }>(
  defaultOpts: IOptions<T, C>
) {
  function createComp(opts: any) {
    const defData: any = cloneDeep(defaultOpts);
    if (defData.children) {
      Object.entries(defData.children).forEach(([key, fn]: any) => {
        defData.children[key] = fn(defData);
      });
    }
    const options = defaultsDeep(opts, defData);

    return new DesignComp(options);
  }

  function useCompData(compId: string) {
    const editor = useEditor();
    const comp = editor.store.designData.compMap[compId];
    return comp as DesignComp & {
      value: T;
      children: { [name in keyof C]: ReturnType<C[name]> };
    };
  }

  function useCreateChild<T extends keyof C>(key: T) {
    const editor = useEditor();
    const createChild: any = (...args: any) => {
      const result = (defaultOpts as any).children[key](defaultOpts, ...args);
      addCacheToMap(editor.store.designData.compMap);
      return result;
    };
    return createChild as C[T];
  }

  return {
    createComp,
    useCompData,
    useCreateChild,
  };
}
