'use client'; import { useCallback, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react'; import { usePlanTier } from '@/entities/plan'; import type { RecentThought } from '@/entities/session'; import { copy } from '@/shared/i18n'; import type { HudStatusLinePayload } from '@/shared/lib/useHudStatusLine'; import type { SpaceAnchorPopoverId, SpaceUtilityPanelId } from './types'; interface UseSpaceToolsDockHandlersParams { setIdle: (idle: boolean) => void; setOpenPopover: (popover: SpaceAnchorPopoverId | null) => void; setUtilityPanel: (panel: SpaceUtilityPanelId | null) => void; onCaptureThought: (note: string) => RecentThought | null; onDeleteThought: (thoughtId: string) => RecentThought | null; onSetThoughtCompleted: (thoughtId: string, isCompleted: boolean) => RecentThought | null; onRestoreThought: (thought: RecentThought) => void; onRestoreThoughts: (thoughts: RecentThought[]) => void; onClearInbox: () => RecentThought[]; onStatusMessage: (payload: HudStatusLinePayload) => void; onSetSoundVolume: (volume: number) => void; onSetSoundMuted: (muted: boolean) => void; soundVolume: number; isSoundMuted: boolean; showVolumeFeedback: (volume: number) => void; } export const useSpaceToolsDockHandlers = ({ setIdle, setOpenPopover, setUtilityPanel, onCaptureThought, onDeleteThought, onSetThoughtCompleted, onRestoreThought, onRestoreThoughts, onClearInbox, onStatusMessage, onSetSoundVolume, onSetSoundMuted, soundVolume, isSoundMuted, showVolumeFeedback, }: UseSpaceToolsDockHandlersParams) => { const { toolsDock } = copy.space; const [noteDraft, setNoteDraft] = useState(''); const { plan, setPlan } = usePlanTier(); const openUtilityPanel = useCallback((panel: SpaceUtilityPanelId) => { setIdle(false); setOpenPopover(null); setUtilityPanel(panel); }, [setIdle, setOpenPopover, setUtilityPanel]); const handleNoteSubmit = useCallback(() => { const trimmedNote = noteDraft.trim(); if (!trimmedNote) { return; } const addedThought = onCaptureThought(trimmedNote); if (!addedThought) { return; } setNoteDraft(''); onStatusMessage({ message: toolsDock.inboxSaved, durationMs: 4200, priority: 'undo', action: { label: toolsDock.undo, onClick: () => { const removed = onDeleteThought(addedThought.id); if (!removed) { return; } onStatusMessage({ message: toolsDock.inboxSaveUndone }); }, }, }); }, [noteDraft, onCaptureThought, onDeleteThought, onStatusMessage, toolsDock.inboxSaved, toolsDock.inboxSaveUndone, toolsDock.undo]); const handleInboxComplete = useCallback((thought: RecentThought) => { onSetThoughtCompleted(thought.id, !thought.isCompleted); }, [onSetThoughtCompleted]); const handleInboxDelete = useCallback((thought: RecentThought) => { const removedThought = onDeleteThought(thought.id); if (!removedThought) { return; } onStatusMessage({ message: toolsDock.deleted, durationMs: 4200, priority: 'undo', action: { label: toolsDock.undo, onClick: () => { onRestoreThought(removedThought); onStatusMessage({ message: toolsDock.deleteUndone }); }, }, }); }, [onDeleteThought, onRestoreThought, onStatusMessage, toolsDock.deleted, toolsDock.deleteUndone, toolsDock.undo]); const handleInboxClear = useCallback(() => { const snapshot = onClearInbox(); if (snapshot.length === 0) { onStatusMessage({ message: toolsDock.emptyToClear }); return; } onStatusMessage({ message: toolsDock.clearedAll, durationMs: 4200, priority: 'undo', action: { label: toolsDock.undo, onClick: () => { onRestoreThoughts(snapshot); onStatusMessage({ message: toolsDock.restored }); }, }, }); }, [onClearInbox, onRestoreThoughts, onStatusMessage, toolsDock.clearedAll, toolsDock.emptyToClear, toolsDock.restored, toolsDock.undo]); const handlePlanPillClick = useCallback(() => { if (plan === 'pro') { openUtilityPanel('manage-plan'); return; } onStatusMessage({ message: toolsDock.normalPlanInfo }); }, [openUtilityPanel, onStatusMessage, plan, toolsDock.normalPlanInfo]); const handleLockedClick = useCallback((source: string) => { onStatusMessage({ message: toolsDock.proFeatureLocked(source) }); openUtilityPanel('paywall'); }, [onStatusMessage, openUtilityPanel, toolsDock]); const handleSelectProFeature = useCallback((featureId: string) => { const label = featureId === 'daily-plan' ? toolsDock.featureLabels.dailyPlan : featureId === 'rituals' ? toolsDock.featureLabels.rituals : toolsDock.featureLabels.weeklyReview; onStatusMessage({ message: toolsDock.proFeaturePending(label) }); }, [onStatusMessage, toolsDock]); const handleStartPro = useCallback(() => { setPlan('pro'); onStatusMessage({ message: toolsDock.purchaseMock }); openUtilityPanel('control-center'); }, [onStatusMessage, openUtilityPanel, setPlan, toolsDock.purchaseMock]); const handleVolumeChange = useCallback((nextVolume: number) => { const clamped = Math.min(100, Math.max(0, nextVolume)); onSetSoundVolume(clamped); if (isSoundMuted && clamped > 0) { onSetSoundMuted(false); } showVolumeFeedback(clamped); }, [isSoundMuted, onSetSoundMuted, onSetSoundVolume, showVolumeFeedback]); const handleVolumeKeyDown = useCallback((event: ReactKeyboardEvent) => { if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') { return; } event.preventDefault(); const step = event.shiftKey ? 10 : 5; const delta = event.key === 'ArrowRight' ? step : -step; handleVolumeChange(soundVolume + delta); }, [handleVolumeChange, soundVolume]); return { noteDraft, setNoteDraft, plan, setPlan, openUtilityPanel, handleNoteSubmit, handleInboxComplete, handleInboxDelete, handleInboxClear, handlePlanPillClick, handleLockedClick, handleSelectProFeature, handleStartPro, handleVolumeChange, handleVolumeKeyDown, }; };