import React, { createContext, useContext } from 'react';
import type { FormikProps } from 'formik';
import { Form } from '@/molecules/form/form';
import type { DynamicFormFieldSchema } from '@/types/dynamic-form-schema-generated';

export interface DynamicFormContextValue {
  formik: FormikProps<Record<string, unknown>>;
  fields: DynamicFormFieldSchema[];
  getFieldValue: (name: string) => unknown;
  getFieldError: (name: string) => string | undefined;
  getFieldTouched: (name: string) => boolean;
  setFieldValue: (field: string, value: unknown) => Promise<void>;
  handleChange: (e: React.ChangeEvent<unknown>) => void;
  handleBlur: (e: React.FocusEvent<unknown>) => void;
}

const DynamicFormContext = createContext<DynamicFormContextValue | null>(null);

interface DynamicFormProviderProps {
  children: React.ReactNode;
  fields: DynamicFormFieldSchema[];
  formik: FormikProps<Record<string, unknown>>;
}

export function DynamicFormProvider({
  children,
  fields,
  formik,
}: DynamicFormProviderProps): React.ReactElement {
  const contextValue: DynamicFormContextValue = {
    formik,
    fields,
    getFieldValue: (name: string): unknown => formik.values[name],
    getFieldError: (name: string): string | undefined => {
      const error = formik.errors[name];
      const touched = formik.touched[name];
      return touched && error ? String(error) : undefined;
    },
    getFieldTouched: (name: string): boolean => Boolean(formik.touched[name]),
    setFieldValue: async (field: string, value: unknown): Promise<void> => {
      await formik.setFieldValue(field, value);
    },
    handleChange: formik.handleChange,
    handleBlur: formik.handleBlur, 
  };

  return (
    <DynamicFormContext.Provider value={contextValue}>
      <Form.Root onSubmit={formik.handleSubmit}>{children}</Form.Root>
    </DynamicFormContext.Provider>
  );
}

export function useDynamicForm(): DynamicFormContextValue {
  const context = useContext(DynamicFormContext);

  if (!context) {
    throw new Error('useDynamicForm must be used within a DynamicFormProvider');
  }

  return context;
}
