import { useState, useCallback } from 'react';

const PREFIX = 'kcg.';

/**
 * localStorage 연동 useState — JSON 직렬화/역직렬화 자동 처리.
 * 새 키가 추가된 Record 타입은 defaults와 자동 머지.
 */
export function useLocalStorage<T>(key: string, defaults: T): [T, (v: T | ((prev: T) => T)) => void] {
  const storageKey = PREFIX + key;

  const [value, setValueRaw] = useState<T>(() => {
    try {
      const raw = localStorage.getItem(storageKey);
      if (raw === null) return defaults;
      const parsed = JSON.parse(raw) as T;
      // Record 타입이면 defaults에 있는 키가 저장값에 없을 때 머지
      if (defaults !== null && typeof defaults === 'object' && !Array.isArray(defaults)) {
        return { ...defaults, ...parsed };
      }
      return parsed;
    } catch {
      return defaults;
    }
  });

  const setValue = useCallback((updater: T | ((prev: T) => T)) => {
    setValueRaw(prev => {
      const next = typeof updater === 'function' ? (updater as (prev: T) => T)(prev) : updater;
      try {
        localStorage.setItem(storageKey, JSON.stringify(next));
      } catch { /* quota exceeded — 무시 */ }
      return next;
    });
  }, [storageKey]);

  return [value, setValue];
}

/**
 * Set<string>용 localStorage 연동 — 내부적으로 Array로 직렬화.
 */
export function useLocalStorageSet(key: string, defaults: Set<string>): [Set<string>, (v: Set<string> | ((prev: Set<string>) => Set<string>)) => void] {
  const storageKey = PREFIX + key;

  const [value, setValueRaw] = useState<Set<string>>(() => {
    try {
      const raw = localStorage.getItem(storageKey);
      if (raw === null) return defaults;
      const arr = JSON.parse(raw);
      return Array.isArray(arr) ? new Set(arr) : defaults;
    } catch {
      return defaults;
    }
  });

  const setValue = useCallback((updater: Set<string> | ((prev: Set<string>) => Set<string>)) => {
    setValueRaw(prev => {
      const next = typeof updater === 'function' ? updater(prev) : updater;
      try {
        localStorage.setItem(storageKey, JSON.stringify(Array.from(next)));
      } catch { /* quota exceeded */ }
      return next;
    });
  }, [storageKey]);

  return [value, setValue];
}
