/**
 * useModal Hook
 *
 * A composable hook for managing modal dialog state.
 * Supports passing data to the modal and optional callbacks.
 *
 * @example
 * ```tsx
 * interface EditUserData {
 *   userId: number;
 *   initialValues: { name: string; email: string };
 * }
 *
 * const editModal = useModal<EditUserData>({
 *   onOpen: (data) => console.log('Opening for user:', data?.userId),
 *   onClose: () => console.log('Modal closed'),
 * });
 *
 * return (
 *   <div>
 *     <button onClick={() => editModal.open({ userId: 1, initialValues: { name: 'John', email: 'john@example.com' } })}>
 *       Edit User
 *     </button>
 *
 *     {editModal.isOpen && (
 *       <Modal onClose={editModal.close}>
 *         <UserForm initialValues={editModal.data?.initialValues} />
 *       </Modal>
 *     )}
 *   </div>
 * );
 * ```
 *
 * ⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
 */

import { useState, useCallback, useRef, useEffect } from 'react';
import type {
  ModalOptions,
  ModalState,
  ModalActions,
  UseModalResult,
} from '../types';

/**
 * Hook for managing modal state.
 *
 * @param options - Modal options
 * @returns Modal state and actions
 */
export function useModal<T = undefined>(
  options: ModalOptions<T> = {}
): UseModalResult<T> {
  const {
    initialOpen = false,
    initialData,
    onOpen,
    onClose,
  } = options;

  const [isOpen, setIsOpen] = useState(initialOpen);
  const [data, setDataState] = useState<T | undefined>(initialData);

  // Track mounted state to avoid state updates after unmount
  const isMountedRef = useRef(true);
  useEffect(() => {
    isMountedRef.current = true;
    return () => {
      isMountedRef.current = false;
    };
  }, []);

  // Actions
  const open = useCallback(
    (newData?: T) => {
      if (!isMountedRef.current) return;
      setDataState(newData);
      setIsOpen(true);
      onOpen?.(newData);
    },
    [onOpen]
  );

  const close = useCallback(() => {
    if (!isMountedRef.current) return;
    setIsOpen(false);
    onClose?.();
  }, [onClose]);

  const toggle = useCallback(() => {
    if (!isMountedRef.current) return;
    if (isOpen) {
      close();
    } else {
      open(data);
    }
  }, [isOpen, close, open, data]);

  const setData = useCallback((newData: T) => {
    if (!isMountedRef.current) return;
    setDataState(newData);
  }, []);

  // Build state object
  const state: ModalState<T> = {
    isOpen,
    data,
  };

  // Build actions object
  const actions: ModalActions<T> = {
    open,
    close,
    toggle,
    setData,
  };

  return {
    ...state,
    ...actions,
  };
}

export default useModal;
