/**
 * CEO 대시보드 targeted refetch 시스템
 *
 * CUD 발생 시 sessionStorage + CustomEvent로 대시보드 섹션별 갱신 트리거
 *
 * 도메인→섹션 매핑은 동적 레지스트리 패턴:
 * - 공통 ERP 도메인은 여기서 직접 등록
 * - 테넌트 전용 도메인은 각 모듈에서 registerDashboardDomain()으로 자기 등록
 */

// 대시보드 섹션 키 (useCEODashboard의 refetchMap과 1:1 매핑)
export type DashboardSectionKey =
  | 'dailyReport'
  | 'receivable'
  | 'debtCollection'
  | 'monthlyExpense'
  | 'cardManagement'
  | 'statusBoard'
  | 'salesStatus'
  | 'purchaseStatus'
  | 'dailyProduction'
  | 'unshipped'
  | 'construction'
  | 'dailyAttendance'
  | 'entertainment'
  | 'welfare';

// 동적 도메인→섹션 레지스트리
const domainSectionRegistry = new Map<string, DashboardSectionKey[]>();

/**
 * 도메인→섹션 매핑 등록 (각 모듈에서 호출)
 *
 * @example
 * // 생산 모듈 초기화 시
 * registerDashboardDomain('production', ['statusBoard', 'dailyProduction']);
 *
 * // 건설 모듈 초기화 시
 * registerDashboardDomain('construction', ['statusBoard', 'construction']);
 */
export function registerDashboardDomain(domain: string, sections: DashboardSectionKey[]): void {
  domainSectionRegistry.set(domain, sections);
}

// ===== 공통 ERP 도메인 (테넌트 무관, 항상 등록) =====
registerDashboardDomain('deposit', ['dailyReport', 'receivable']);
registerDashboardDomain('withdrawal', ['dailyReport', 'monthlyExpense']);
registerDashboardDomain('sales', ['dailyReport', 'salesStatus', 'receivable']);
registerDashboardDomain('purchase', ['dailyReport', 'purchaseStatus', 'monthlyExpense']);
registerDashboardDomain('badDebt', ['debtCollection', 'receivable']);
registerDashboardDomain('expectedExpense', ['monthlyExpense']);
registerDashboardDomain('bill', ['dailyReport', 'receivable']);
registerDashboardDomain('giftCertificate', ['entertainment', 'cardManagement']);
registerDashboardDomain('journalEntry', ['entertainment', 'welfare', 'monthlyExpense']);
registerDashboardDomain('order', ['statusBoard', 'salesStatus']);
registerDashboardDomain('stock', ['statusBoard']);
registerDashboardDomain('schedule', ['statusBoard']);
registerDashboardDomain('client', ['statusBoard']);
registerDashboardDomain('leave', ['statusBoard', 'dailyAttendance']);
registerDashboardDomain('approval', ['statusBoard']);
registerDashboardDomain('attendance', ['statusBoard', 'dailyAttendance']);
registerDashboardDomain('shipment', ['statusBoard', 'unshipped']);

// ===== 테넌트 전용 도메인 (각 모듈에서 등록 — 현재는 하위 호환을 위해 여기서도 등록) =====
// TODO: Phase 1 완료 후 각 모듈의 초기화 코드로 이동
registerDashboardDomain('production', ['statusBoard', 'dailyProduction']);
registerDashboardDomain('construction', ['statusBoard', 'construction']);

const STORAGE_KEY = 'dashboard:stale-sections';
const EVENT_NAME = 'dashboard:invalidate';

/**
 * CUD 성공 후 호출 — 해당 도메인이 영향 주는 대시보드 섹션을 stale 처리
 */
export function invalidateDashboard(domain: string): void {
  const sections = domainSectionRegistry.get(domain);
  if (!sections || sections.length === 0) return;

  // 1. sessionStorage에 stale 섹션 저장 (navigation 사이 유지)
  try {
    const existing = sessionStorage.getItem(STORAGE_KEY);
    const current: string[] = existing ? JSON.parse(existing) : [];
    const merged = Array.from(new Set([...current, ...sections]));
    sessionStorage.setItem(STORAGE_KEY, JSON.stringify(merged));
  } catch {
    // sessionStorage 접근 불가 시 무시
  }

  // 2. CustomEvent 발행 (대시보드가 마운트 중이면 즉시 처리)
  if (typeof window !== 'undefined') {
    window.dispatchEvent(
      new CustomEvent(EVENT_NAME, { detail: { sections } }),
    );
  }
}

/**
 * 대시보드 마운트 시 호출 — stale 섹션 읽고 클리어
 */
export function consumeStaleSections(): DashboardSectionKey[] {
  try {
    const raw = sessionStorage.getItem(STORAGE_KEY);
    if (!raw) return [];
    sessionStorage.removeItem(STORAGE_KEY);
    return JSON.parse(raw) as DashboardSectionKey[];
  } catch {
    return [];
  }
}

/** CustomEvent 이름 (리스너 등록용) */
export const DASHBOARD_INVALIDATE_EVENT = EVENT_NAME;
