import { notify } from "@kyvg/vue3-notification";

/**
 * Vuelidate field validator interface for type checking.
 * This is a simplified version of the actual vuelidate type.
 */
interface FieldValidator {
  $error: boolean;
  $errors?: Array<{ $message: string }>;
  $validate?: () => Promise<boolean>;
}

/**
 * Composable for consistent form validation styling and behavior across the app.
 *
 * Provides:
 * - Input class helper that adds 'input-error' when field has validation errors
 * - Select class helper that adds 'select-error' when field has validation errors
 * - Textarea class helper that adds 'textarea-error' when field has validation errors
 * - Standardized form validation with popup notification
 */
export function useFormValidation() {
  /**
   * Returns input classes with error styling when validation fails.
   * Use with :class binding on input elements.
   *
   * @param fieldValidator - The vuelidate field validator (e.g., v$.form.fieldName)
   * @param baseClasses - Optional base classes to include (default: 'input input-bordered input-sm w-full')
   * @returns Object with class bindings
   *
   * @example
   * <input :class="inputClasses(v$.form.email)" v-model="form.email" />
   */
  const inputClasses = (
    fieldValidator: FieldValidator | undefined,
    baseClasses: string = 'input input-bordered input-sm w-full'
  ): Record<string, boolean> | string => {
    if (!fieldValidator) {
      return baseClasses;
    }
    return {
      [baseClasses]: true,
      'input-error': fieldValidator.$error === true,
    };
  };

  /**
   * Returns select classes with error styling when validation fails.
   *
   * @param fieldValidator - The vuelidate field validator
   * @param baseClasses - Optional base classes (default: 'select select-bordered select-sm w-full')
   */
  const selectClasses = (
    fieldValidator: FieldValidator | undefined,
    baseClasses: string = 'select select-bordered select-sm w-full'
  ): Record<string, boolean> | string => {
    if (!fieldValidator) {
      return baseClasses;
    }
    return {
      [baseClasses]: true,
      'select-error': fieldValidator.$error === true,
    };
  };

  /**
   * Returns textarea classes with error styling when validation fails.
   *
   * @param fieldValidator - The vuelidate field validator
   * @param baseClasses - Optional base classes (default: 'textarea textarea-bordered')
   */
  const textareaClasses = (
    fieldValidator: FieldValidator | undefined,
    baseClasses: string = 'textarea textarea-bordered'
  ): Record<string, boolean> | string => {
    if (!fieldValidator) {
      return baseClasses;
    }
    return {
      [baseClasses]: true,
      'textarea-error': fieldValidator.$error === true,
    };
  };

  /**
   * Validates the form and shows a popup notification if validation fails.
   * Returns true if form is valid, false otherwise.
   *
   * @param v$ - The vuelidate instance
   * @param errorTitle - Title for the error notification (default: 'Validation Error')
   * @param errorMessage - Message for the error notification (default: 'Please fill out all required fields correctly.')
   * @returns Promise<boolean> - true if valid, false if invalid
   *
   * @example
   * const onSubmit = async () => {
   *   if (await validateForm(v$)) {
   *     // Submit the form
   *   }
   * }
   */
  const validateForm = async (
    v$: { value: { $validate: () => Promise<boolean> } },
    errorTitle: string = 'Validation Error',
    errorMessage: string = 'Please fill out all required fields correctly.'
  ): Promise<boolean> => {
    const isValid = await v$.value.$validate();

    if (!isValid) {
      notify({
        title: errorTitle,
        text: errorMessage,
        type: 'error',
      });
    }

    return isValid;
  };

  /**
   * Gets the first error message for a field, or empty string if no error.
   *
   * @param fieldValidator - The vuelidate field validator
   * @returns The error message string or empty string
   */
  const getErrorMessage = (fieldValidator: FieldValidator | undefined): string => {
    if (!fieldValidator || !fieldValidator.$error || !fieldValidator.$errors?.length) {
      return '';
    }
    return fieldValidator.$errors[0].$message as string;
  };

  /**
   * Checks if a field has an error.
   *
   * @param fieldValidator - The vuelidate field validator
   * @returns boolean - true if field has error
   */
  const hasError = (fieldValidator: FieldValidator | undefined): boolean => {
    return fieldValidator?.$error === true;
  };

  return {
    inputClasses,
    selectClasses,
    textareaClasses,
    validateForm,
    getErrorMessage,
    hasError,
  };
}
