import {
  createContext,
  useContext,
  useState,
  ReactNode,
  useMemo,
  useCallback,
} from 'react';

export type PartialFormulaContextItem = {
  id: string | number;
  mathExpression: string | null;
};

export type FormulasContextType = {
  formulas: PartialFormulaContextItem[];
  resetFormulas: () => void;
  setFormula: (rangeIndex: number, expression: string) => void;
  updateFormulas: (items: PartialFormulaContextItem[]) => void;
};

const FormulasContext = createContext<FormulasContextType | null>(null);

export const FormulasProvider = ({ children }: { children: ReactNode }) => {
  const [formulas, setFormulas] = useState<PartialFormulaContextItem[]>([]);

  const setFormula = useCallback(
    (rangeIndex: number, mathExpression: string) => {
      setFormulas(prev => {
        const newValue = mathExpression.trim() || null;
        if (prev[rangeIndex]?.mathExpression === newValue) {
          return prev;
        }
        const newArr = [...prev];
        newArr[rangeIndex] = {
          id: newArr[rangeIndex]?.id ?? rangeIndex,
          mathExpression: newValue,
        };
        return newArr;
      });
    },
    [],
  );

  const resetFormulas = useCallback(() => {
    setFormulas([]);
  }, []);

  const updateFormulas = useCallback((items: PartialFormulaContextItem[]) => {
    setFormulas(
      items.map((item, idx) => ({
        id: item.id !== undefined ? item.id : String(idx),
        mathExpression: item.mathExpression?.trim() || null,
      })),
    );
  }, []);

  const value = useMemo(
    () => ({
      formulas,
      setFormula,
      resetFormulas,
      updateFormulas,
    }),
    [formulas, setFormula, resetFormulas, updateFormulas],
  );

  return (
    <FormulasContext.Provider value={value}>
      {children}
    </FormulasContext.Provider>
  );
};

export const useFormulas = () => {
  const context = useContext(FormulasContext);
  if (!context) {
    throw new Error('useFormulas must be used within a FormulasProvider');
  }
  return context;
};
