// ConfigForm - Main RJSF form wrapper component
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";
import type { RJSFSchema, UiSchema } from "@rjsf/utils";
import type { IChangeEvent } from "@rjsf/core";
import { frigateTheme } from "./theme";
import { transformSchema } from "@/lib/config-schema";
import { createErrorTransformer } from "@/lib/config-schema/errorMessages";
import { useMemo, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { cn } from "@/lib/utils";

export interface ConfigFormProps {
  /** JSON Schema for the form */
  schema: RJSFSchema;
  /** Current form data */
  formData?: unknown;
  /** Called when form data changes */
  onChange?: (data: unknown) => void;
  /** Called when form is submitted */
  onSubmit?: (data: unknown) => void;
  /** Called when form has errors on submit */
  onError?: (errors: unknown[]) => void;
  /** Additional uiSchema overrides */
  uiSchema?: UiSchema;
  /** Field ordering */
  fieldOrder?: string[];
  /** Field groups for layout */
  fieldGroups?: Record<string, string[]>;
  /** Fields to hide */
  hiddenFields?: string[];
  /** Fields marked as advanced (collapsed by default) */
  advancedFields?: string[];
  /** Whether form is disabled */
  disabled?: boolean;
  /** Whether form is read-only */
  readonly?: boolean;
  /** Whether to show submit button */
  showSubmit?: boolean;
  /** Custom class name */
  className?: string;
  /** Live validation mode */
  liveValidate?: boolean;
  /** Form context passed to all widgets */
  formContext?: Record<string, unknown>;
  /** i18n namespace for field labels */
  i18nNamespace?: string;
}

export function ConfigForm({
  schema,
  formData,
  onChange,
  onSubmit,
  onError,
  uiSchema: customUiSchema,
  fieldOrder,
  fieldGroups,
  hiddenFields,
  advancedFields,
  disabled = false,
  readonly = false,
  showSubmit = false,
  className,
  liveValidate = true,
  formContext,
  i18nNamespace,
}: ConfigFormProps) {
  const { t, i18n } = useTranslation([
    i18nNamespace || "common",
    "views/settings",
    "config/validation",
  ]);

  // Determine which fields to hide based on advanced toggle
  const effectiveHiddenFields = useMemo(() => {
    return hiddenFields;
  }, [hiddenFields]);

  // Transform schema and generate uiSchema
  const { schema: transformedSchema, uiSchema: generatedUiSchema } = useMemo(
    () =>
      transformSchema(schema, {
        fieldOrder,
        hiddenFields: effectiveHiddenFields,
        advancedFields: advancedFields,
        i18nNamespace,
      }),
    [schema, fieldOrder, effectiveHiddenFields, advancedFields, i18nNamespace],
  );

  // Merge generated uiSchema with custom overrides
  const finalUiSchema = useMemo(
    () => ({
      ...generatedUiSchema,
      "ui:groups": fieldGroups,
      ...customUiSchema,
      "ui:submitButtonOptions": showSubmit
        ? { norender: false }
        : { norender: true },
    }),
    [generatedUiSchema, customUiSchema, showSubmit, fieldGroups],
  );

  // Create error transformer for user-friendly error messages
  const errorTransformer = useMemo(() => createErrorTransformer(i18n), [i18n]);

  const handleChange = useCallback(
    (e: IChangeEvent) => {
      onChange?.(e.formData);
    },
    [onChange],
  );

  const handleSubmit = useCallback(
    (e: IChangeEvent) => {
      onSubmit?.(e.formData);
    },
    [onSubmit],
  );

  // Extended form context with i18n info
  const extendedFormContext = useMemo(
    () => ({
      ...formContext,
      i18nNamespace,
      t,
    }),
    [formContext, i18nNamespace, t],
  );

  return (
    <div className={cn("config-form", className)}>
      <Form
        schema={transformedSchema}
        uiSchema={finalUiSchema}
        formData={formData}
        validator={validator}
        onChange={handleChange}
        onSubmit={handleSubmit}
        onError={onError}
        disabled={disabled}
        readonly={readonly}
        liveValidate={liveValidate}
        formContext={extendedFormContext}
        transformErrors={errorTransformer}
        {...frigateTheme}
      />
    </div>
  );
}

export default ConfigForm;
