import "./style.pcss";

import type {
  FC, CSSProperties, ReactElement,
} from "react";
import { createElement, useMemo } from "react";
import { defaultGaps, defaultColumns } from "./config";
import type { IGrid } from "./config/types";
import { GridContext } from "./context";
import {
  getColumnsAdapter,
  isSameObjects,
  getGapAdapter,
  getPropAdapter,
} from "./lib";
import { GridItem } from "./ui/GridItem";
import type { IComponentBaseProps } from "../../types/components/index";
import { useCN } from "../../utils/react/useCN";

/**
 * Компонент сетки
 * @returns {ReactElement}

 */
const Grid: FC<IComponentBaseProps & IGrid> = ({
  baseClass = "grid",
  extraClasses = {},
  extraAttrs = {},
  style = {} as CSSProperties,
  tag = "div",
  type = "flex",
  columns = defaultColumns as IGrid["columns"],
  gaps = defaultGaps as IGrid["gaps"],
  align,
  justify,
  children = null,
}): ReactElement => {

  const { getCN } = useCN(baseClass);

  const styles = useMemo(() => {

    const props: {
      [key: string]: string | number;
    } = { ...(style || {}) };

    const computedColumns = getColumnsAdapter(columns);
    if (!isSameObjects(computedColumns, defaultColumns)) {
      const [ columnsDesktop, columnsTablet, columnsMobile ] = computedColumns;
      props["--gridColumnsDesktop"] = columnsDesktop;
      props["--gridColumnsTablet"] = columnsTablet;
      props["--gridColumnsMobile"] = columnsMobile;
    }

    const computedGaps = getGapAdapter(gaps);
    if (!isSameObjects(computedGaps, defaultGaps)) {
      const [ gapsDesktop, gapsTablet, gapsMobile ] = computedGaps;
      props["--gridGapDesktop"] = gapsDesktop;
      props["--gridGapTablet"] = gapsTablet;
      props["--gridGapMobile"] = gapsMobile;
    }

    if (align) {
      const [ alignDesktop, alignTablet, alignMobile ] = getPropAdapter(align);
      props["--gridAlignItemsDesktop"] = alignDesktop;
      props["--gridAlignItemsTablet"] = alignTablet;
      props["--gridAlignItemsMobile"] = alignMobile;
    }

    if (justify) {
      const [ justifyDesktop, justifyTablet, justifyMobile ] = getPropAdapter(justify);
      props["--gridJustifyContentDesktop"] = justifyDesktop;
      props["--gridJustifyContentTablet"] = justifyTablet;
      props["--gridJustifyContentMobile"] = justifyMobile;
    }

    return props;
  }, [ align, columns, gaps, justify, style ]);

  const ctx = useMemo(() => ({ getCN, tag, styles }), [ getCN, tag, styles ]);

  return (
    <GridContext value={ctx}>
      {createElement(tag, {
        style: styles,
        ...extraAttrs,
        className: getCN("", {
          isFlex: type === "flex",
          isGrid: type === "grid",
          ...extraClasses,
        }),
      }, children)}
    </GridContext>
  );

};

export type { IGrid };
export { Grid, GridItem };
