import React, { useContext, useEffect } from 'react';
import { ModeType } from '../silke-color-swatches';

export type SilkeCSSContextType = {
  fontSize?: number;
  /**
   * Viewport is the size of the window/viewport
   * Required to be able to convert from/to vh/vw/vmin/vmax in SilkeCSSNumberField
   */
  viewport: [width: number, height: number];
  /**
   * Container is the size of the holder element,
   * required to be able to convert from/to % format in SilkeCssNumberField
   * */
  container?: [width: number, height: number];
  /**
   * Self is the size of the element itself,
   * required to be able convert auto into any other format in SilkeCssNumberField
   */
  self?: [width: number, height: number];
  variables: { [variableName: string]: string };
  variablesv2: {
    key: string;
    name: string;
    type: 'color' | 'number' | 'font' | 'text' | 'image';
    value?: string;
    unit?: string;
    default?: boolean;
    hidden?: boolean;
    group?: string;
  }[];
  preferredColorMode?: ModeType;
  readonly?: boolean;
  getFontName?: (fontKey: string) => string;
  onVariableAdd?: (color: string) => void;
  onVariableDelete?: (color: string) => void;
  onVariableAttached?: (type: string) => void;
  onPreferredColorModeChange?: (mode: ModeType) => void;
};

const Context = React.createContext<SilkeCSSContextType>({
  fontSize: 14,
  viewport: [1440, 900],
  variables: {},
  variablesv2: [],
  preferredColorMode: undefined,
  getFontName: () => '',
  onVariableAdd: () => null,
  onVariableDelete: () => null,
  onVariableAttached: () => null,
  onPreferredColorModeChange: () => null,
});
Context.displayName = 'SilkeTextFieldContext';

export function useSilkeCSSContext() {
  return useContext(Context);
}

export function SilkeCSSContext({
  children,
  ...rest
}: Partial<SilkeCSSContextType> & { children: React.ReactNode }) {
  const context = useContext(Context);
  const { variables, variablesv2 } = rest;

  useEffect(() => {
    if (variables) {
      const style = document.createElement('style');
      style.innerText = `body{${Object.entries(variables)
        .map(([name, value]) => `${name}:${value}`)
        .join(';')}}`;

      document.body.appendChild(style);
      return () => style.remove();
    }
  }, [variables]);

  useEffect(() => {
    if (variablesv2) {
      const style = document.createElement('style');
      style.innerText = `body{${variablesv2
        .map((v) => `--vev-${v.key}:${v.value}${v.unit ? v.unit : ''}`)
        .join(';')}}`;

      document.body.appendChild(style);
      return () => style.remove();
    }
  }, [variablesv2]);

  return <Context.Provider value={{ ...context, ...rest }}>{children}</Context.Provider>;
}
