/**
 * 화면 컨텍스트
 * 같은 화면 내의 컴포넌트들이 서로 통신할 수 있도록 합니다.
 */

"use client";

import React, { createContext, useContext, useCallback, useRef } from "react";
import type { DataProvidable, DataReceivable } from "@/types/data-transfer";
import { logger } from "@/lib/utils/logger";

interface ScreenContextValue {
  screenId?: number;
  tableName?: string;
  
  // 컴포넌트 등록
  registerDataProvider: (componentId: string, provider: DataProvidable) => void;
  unregisterDataProvider: (componentId: string) => void;
  registerDataReceiver: (componentId: string, receiver: DataReceivable) => void;
  unregisterDataReceiver: (componentId: string) => void;
  
  // 컴포넌트 조회
  getDataProvider: (componentId: string) => DataProvidable | undefined;
  getDataReceiver: (componentId: string) => DataReceivable | undefined;
  
  // 모든 컴포넌트 조회
  getAllDataProviders: () => Map<string, DataProvidable>;
  getAllDataReceivers: () => Map<string, DataReceivable>;
}

const ScreenContext = createContext<ScreenContextValue | null>(null);

interface ScreenContextProviderProps {
  screenId?: number;
  tableName?: string;
  children: React.ReactNode;
}

/**
 * 화면 컨텍스트 프로바이더
 */
export function ScreenContextProvider({ screenId, tableName, children }: ScreenContextProviderProps) {
  const dataProvidersRef = useRef<Map<string, DataProvidable>>(new Map());
  const dataReceiversRef = useRef<Map<string, DataReceivable>>(new Map());

  const registerDataProvider = useCallback((componentId: string, provider: DataProvidable) => {
    dataProvidersRef.current.set(componentId, provider);
    logger.debug("데이터 제공자 등록", { componentId, componentType: provider.componentType });
  }, []);

  const unregisterDataProvider = useCallback((componentId: string) => {
    dataProvidersRef.current.delete(componentId);
    logger.debug("데이터 제공자 해제", { componentId });
  }, []);

  const registerDataReceiver = useCallback((componentId: string, receiver: DataReceivable) => {
    dataReceiversRef.current.set(componentId, receiver);
    logger.debug("데이터 수신자 등록", { componentId, componentType: receiver.componentType });
  }, []);

  const unregisterDataReceiver = useCallback((componentId: string) => {
    dataReceiversRef.current.delete(componentId);
    logger.debug("데이터 수신자 해제", { componentId });
  }, []);

  const getDataProvider = useCallback((componentId: string) => {
    return dataProvidersRef.current.get(componentId);
  }, []);

  const getDataReceiver = useCallback((componentId: string) => {
    return dataReceiversRef.current.get(componentId);
  }, []);

  const getAllDataProviders = useCallback(() => {
    return new Map(dataProvidersRef.current);
  }, []);

  const getAllDataReceivers = useCallback(() => {
    return new Map(dataReceiversRef.current);
  }, []);

  const value: ScreenContextValue = {
    screenId,
    tableName,
    registerDataProvider,
    unregisterDataProvider,
    registerDataReceiver,
    unregisterDataReceiver,
    getDataProvider,
    getDataReceiver,
    getAllDataProviders,
    getAllDataReceivers,
  };

  return <ScreenContext.Provider value={value}>{children}</ScreenContext.Provider>;
}

/**
 * 화면 컨텍스트 훅
 */
export function useScreenContext() {
  const context = useContext(ScreenContext);
  if (!context) {
    throw new Error("useScreenContext는 ScreenContextProvider 내부에서만 사용할 수 있습니다.");
  }
  return context;
}

/**
 * 화면 컨텍스트 훅 (선택적)
 * 컨텍스트가 없어도 에러를 발생시키지 않습니다.
 */
export function useScreenContextOptional() {
  return useContext(ScreenContext);
}

