/**
 * 캔버스 분할선 글로벌 스토어
 *
 * 성능 최적화: 이중 리스너 구조
 * - React 리스너 (subscribe): 구조적 변경만 알림 (active, isDragging 시작/종료)
 * - DOM 리스너 (subscribeDom): 드래그 중 위치 변경 알림 (React 우회, 직접 DOM 조작)
 */

export interface CanvasSplitState {
  initialDividerX: number;
  currentDividerX: number;
  canvasWidth: number;
  isDragging: boolean;
  active: boolean;
  scopeId: string;
}

const initialState: CanvasSplitState = {
  initialDividerX: 0,
  currentDividerX: 0,
  canvasWidth: 0,
  isDragging: false,
  active: false,
  scopeId: "",
};

let state: CanvasSplitState = { ...initialState };

// React 리렌더링을 트리거하는 리스너 (구조적 변경 전용)
const reactListeners = new Set<() => void>();

// DOM 직접 조작용 리스너 (드래그 중 위치 업데이트, React 우회)
const domListeners = new Set<(state: CanvasSplitState) => void>();

// React용 스냅샷 (드래그 중 위치 변경에는 갱신 안 함)
let reactSnapshot: CanvasSplitState = { ...initialState };

export function setCanvasSplit(updates: Partial<CanvasSplitState>): void {
  state = { ...state, ...updates };

  // 드래그 중 위치만 변경 → DOM 리스너만 호출 (React 리렌더 없음)
  const isPositionOnlyDuringDrag =
    state.isDragging &&
    Object.keys(updates).length === 1 &&
    "currentDividerX" in updates;

  if (isPositionOnlyDuringDrag) {
    domListeners.forEach((fn) => fn(state));
    return;
  }

  // 구조적 변경 → React 리스너 + DOM 리스너 모두 호출
  reactSnapshot = { ...state };
  reactListeners.forEach((fn) => fn());
  domListeners.forEach((fn) => fn(state));
}

export function resetCanvasSplit(): void {
  state = { ...initialState };
  reactSnapshot = { ...initialState };
  reactListeners.forEach((fn) => fn());
  domListeners.forEach((fn) => fn(state));
}

// React용: useSyncExternalStore에 연결
export function subscribe(callback: () => void): () => void {
  reactListeners.add(callback);
  return () => {
    reactListeners.delete(callback);
  };
}

export function getSnapshot(): CanvasSplitState {
  return reactSnapshot;
}

export function getServerSnapshot(): CanvasSplitState {
  return { ...initialState };
}

// DOM 직접 조작용: 드래그 중 매 프레임 위치 업데이트 수신
export function subscribeDom(
  callback: (state: CanvasSplitState) => void,
): () => void {
  domListeners.add(callback);
  return () => {
    domListeners.delete(callback);
  };
}

// 현재 상태 직접 참조 (DOM 리스너 콜백 외부에서 최신 상태 필요 시)
export function getCurrentState(): CanvasSplitState {
  return state;
}
