import { useEffect, type RefObject } from 'react';
import { THEME_CHANGE_EVENT } from '../lib/theme';
import { deriveSpaceBrandVars, type BrandVars } from '../lib/spaceBranding';

const VAR_NAMES: Array<keyof BrandVars> = [
  '--brand-primary',
  '--brand-primary-deep',
  '--brand-primary-soft',
  '--brand-primary-ring',
  '--brand-primary-fg',
];

/**
 * スペースのブランド色を、詳細パネルのコンテナ要素に scoped で適用する。
 * - `brandColor` があり、かつパースできる → 5 つの --brand-primary 系変数を ref 要素に inline-set。
 *   子孫の `text-accent` / `bg-accent` 等（CSS 変数参照）がスペース色になる。
 * - soft tint はテーマ依存なので、テーマ切替・OS の dark 設定変更で再導出する。
 * - スペースを離れる / brandColor が消える / アンマウント時は変数を削除し、
 *   グローバル（useBranding が documentElement に置いた既定値）へ自然に戻す。
 *
 * `useBranding` は documentElement（:root）に対してアプリ全体のブランド色を適用するが、
 * こちらは特定コンテナへの上書きなので両者は競合しない（より内側のスコープが勝つ）。
 */
export function useSpaceBranding(
  containerRef: RefObject<HTMLElement>,
  brandColor: string | null | undefined,
): void {
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;

    const clear = () => {
      for (const name of VAR_NAMES) el.style.removeProperty(name);
    };

    if (!brandColor) {
      clear();
      return;
    }

    const apply = () => {
      const isDark = document.documentElement.dataset.theme === 'dark';
      const vars = deriveSpaceBrandVars(brandColor, isDark);
      if (!vars) {
        // パース不能な色は scoped 適用しない（既定 branding に委ねる）。
        clear();
        return;
      }
      for (const name of VAR_NAMES) el.style.setProperty(name, vars[name]);
    };

    apply();
    window.addEventListener(THEME_CHANGE_EVENT, apply);
    const mq = window.matchMedia('(prefers-color-scheme: dark)');
    mq.addEventListener('change', apply);

    return () => {
      window.removeEventListener(THEME_CHANGE_EVENT, apply);
      mq.removeEventListener('change', apply);
      clear();
    };
  }, [containerRef, brandColor]);
}
