/**
 * useCanvasSettings Hook
 *
 * Main hook for managing canvas settings (event-action mappings and presets).
 * Provides both read access to settings and methods to modify them.
 */

import { useAtomValue, useSetAtom } from 'jotai';

import {
	type CanvasEventType,
	type EventActionMapping,
	type SettingsPreset,
} from '../core/settings-types';

import {
	eventMappingsAtom,
	activePresetIdAtom,
	activePresetAtom,
	allPresetsAtom,
	hasUnsavedChangesAtom,
	isPanelOpenAtom,
	setEventMappingAtom,
	applyPresetAtom,
	saveAsPresetAtom,
	updatePresetAtom,
	deletePresetAtom,
	resetSettingsAtom,
	togglePanelAtom,
	setPanelOpenAtom,
	getActionForEvent,
} from '../core/settings-store';

// =============================================================================
// Hook Return Type
// =============================================================================

export interface UseCanvasSettingsReturn {
	// Read-only state
	/** Current event-action mappings */
	mappings: EventActionMapping;
	/** ID of the currently active preset (null if modified) */
	activePresetId: string | null;
	/** The currently active preset object (null if modified) */
	activePreset: SettingsPreset | null;
	/** All available presets (built-in + custom) */
	allPresets: SettingsPreset[];
	/** Whether current mappings differ from the active preset */
	hasUnsavedChanges: boolean;
	/** Whether the settings panel is open */
	isPanelOpen: boolean;

	// Actions
	/** Set the action for a specific event */
	setEventMapping: (event: CanvasEventType, actionId: string) => void;
	/** Apply a preset (copies its mappings) */
	applyPreset: (presetId: string) => void;
	/** Save current mappings as a new custom preset */
	saveAsPreset: (name: string, description?: string) => string;
	/** Update an existing custom preset with current mappings */
	updatePreset: (presetId: string) => void;
	/** Delete a custom preset */
	deletePreset: (presetId: string) => void;
	/** Reset to default settings */
	resetSettings: () => void;
	/** Toggle the settings panel */
	togglePanel: () => void;
	/** Set panel open state directly */
	setPanelOpen: (isOpen: boolean) => void;

	// Utilities
	/** Get the action ID for a specific event */
	getActionForEvent: (event: CanvasEventType) => string;
}

// =============================================================================
// Hook Implementation
// =============================================================================

/**
 * Hook for managing canvas event-action settings.
 *
 * @example
 * ```tsx
 * function CanvasSettingsButton() {
 *   const {
 *     isPanelOpen,
 *     togglePanel,
 *     activePreset,
 *     hasUnsavedChanges,
 *   } = useCanvasSettings();
 *
 *   return (
 *     <button onClick={togglePanel}>
 *       Settings
 *       {hasUnsavedChanges && '*'}
 *     </button>
 *   );
 * }
 * ```
 *
 * @example
 * ```tsx
 * function PresetSelector() {
 *   const { allPresets, activePresetId, applyPreset } = useCanvasSettings();
 *
 *   return (
 *     <select
 *       value={activePresetId || ''}
 *       onChange={(e) => applyPreset(e.target.value)}
 *     >
 *       {allPresets.map((preset) => (
 *         <option key={preset.id} value={preset.id}>
 *           {preset.name}
 *         </option>
 *       ))}
 *     </select>
 *   );
 * }
 * ```
 */
export function useCanvasSettings(): UseCanvasSettingsReturn {
	// Read-only atoms
	const mappings = useAtomValue(eventMappingsAtom);
	const activePresetId = useAtomValue(activePresetIdAtom);
	const activePreset = useAtomValue(activePresetAtom);
	const allPresets = useAtomValue(allPresetsAtom);
	const hasUnsavedChanges = useAtomValue(hasUnsavedChangesAtom);
	const isPanelOpen = useAtomValue(isPanelOpenAtom);

	// Action atoms
	const setEventMappingAction = useSetAtom(setEventMappingAtom);
	const applyPresetAction = useSetAtom(applyPresetAtom);
	const saveAsPresetAction = useSetAtom(saveAsPresetAtom);
	const updatePresetAction = useSetAtom(updatePresetAtom);
	const deletePresetAction = useSetAtom(deletePresetAtom);
	const resetSettingsAction = useSetAtom(resetSettingsAtom);
	const togglePanelAction = useSetAtom(togglePanelAtom);
	const setPanelOpenAction = useSetAtom(setPanelOpenAtom);

	// Wrapped actions
	const setEventMapping = (event: CanvasEventType, actionId: string) => {
		setEventMappingAction({ event, actionId });
	};

	const applyPreset = (presetId: string) => {
		applyPresetAction(presetId);
	};

	const saveAsPreset = (name: string, description?: string): string => {
		return saveAsPresetAction({ name, description }) as string;
	};

	const updatePreset = (presetId: string) => {
		updatePresetAction(presetId);
	};

	const deletePreset = (presetId: string) => {
		deletePresetAction(presetId);
	};

	const resetSettings = () => {
		resetSettingsAction();
	};

	const togglePanel = () => {
		togglePanelAction();
	};

	const setPanelOpen = (isOpen: boolean) => {
		setPanelOpenAction(isOpen);
	};

	const getActionForEventFn = (event: CanvasEventType): string => {
		return getActionForEvent(mappings, event);
	};

	return {
		// State
		mappings,
		activePresetId,
		activePreset,
		allPresets,
		hasUnsavedChanges,
		isPanelOpen,

		// Actions
		setEventMapping,
		applyPreset,
		saveAsPreset,
		updatePreset,
		deletePreset,
		resetSettings,
		togglePanel,
		setPanelOpen,

		// Utilities
		getActionForEvent: getActionForEventFn,
	};
}
