// packages/core/src/components/form/form-context.ts
import type { Accessor } from "solid-js";
import { createContext, useContext } from "solid-js";

// ─── Root Form Context ─────────────────────────────────────────────────────

export interface FormContextValue {
  /** Reactive map of field name -> error messages */
  errors: Accessor<Record<string, string[]>>;
  /** Get error messages for a specific field */
  getFieldErrors: (name: string) => string[];
  /** Register a field value (used by FormField on blur/change) */
  setFieldValue: (name: string, value: unknown) => void;
  /** Get the current value of a field */
  getFieldValue: (name: string) => unknown;
  /** Validate a single field against the schema */
  validateField: (name: string) => void;
  /** Validate all fields; returns true if valid */
  validateAll: () => boolean;
  /** Whether the entire form is disabled */
  disabled: Accessor<boolean>;
  /** When validation is triggered */
  validateOn: Accessor<"submit" | "blur" | "change">;
}

const FormContext = createContext<FormContextValue>();

/**
 * Returns the internal Form context value.
 * Throws if used outside of a Form root.
 */
export function useFormContext(): FormContextValue {
  const ctx = useContext(FormContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] Form parts must be used inside <Form>.\n" +
        "  Fix: Wrap your Form.Field, Form.Submit, etc. inside <Form>.\n" +
        "  Docs: https://pettyui.dev/components/form#composition",
    );
  }
  return ctx;
}

export const FormContextProvider = FormContext.Provider;

// ─── Per-Field Context ─────────────────────────────────────────────────────

export interface FormFieldContextValue {
  /** Field name, matches schema key */
  name: string;
  /** ID for the control element (used by label htmlFor) */
  controlId: string;
  /** ID for the description element */
  descriptionId: string;
  /** ID for the error message element */
  errorId: string;
  /** Reactive error messages for this field */
  errors: Accessor<string[]>;
}

const FormFieldContext = createContext<FormFieldContextValue>();

/**
 * Returns the per-field Form context value.
 * Throws if used outside of a Form.Field.
 */
export function useFormFieldContext(): FormFieldContextValue {
  const ctx = useContext(FormFieldContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] Form sub-components must be used inside <Form.Field>.\n" +
        "  Fix: Wrap Form.Label, Form.Control, Form.ErrorMessage inside <Form.Field>.\n" +
        "  Docs: https://pettyui.dev/components/form#composition",
    );
  }
  return ctx;
}

export const FormFieldContextProvider = FormFieldContext.Provider;
