// スペースのブランド色から派生カラー（--brand-primary 系 5 変数）を計算する純関数。
// useBranding.ts の applyBrandColors と同じ導出ロジックを、DOM 非依存の形で切り出したもの。
// useSpaceBranding がこの結果をスペース詳細コンテナへ scoped 適用する。

export interface BrandVars {
  '--brand-primary': string;
  '--brand-primary-deep': string;
  '--brand-primary-soft': string;
  '--brand-primary-ring': string;
  '--brand-primary-fg': string;
}

interface Rgb { r: number; g: number; b: number }

export function parseColor(input: string): Rgb | null {
  const s = input.trim();
  const hex = s.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
  if (hex) {
    const h = hex[1];
    const full = h.length === 3 ? h.split('').map(c => c + c).join('') : h;
    return {
      r: parseInt(full.slice(0, 2), 16),
      g: parseInt(full.slice(2, 4), 16),
      b: parseInt(full.slice(4, 6), 16),
    };
  }
  const rgb = s.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
  if (rgb) {
    return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]) };
  }
  return null;
}

function rgbToHsl({ r, g, b }: Rgb): { h: number; s: number; l: number } {
  const rn = r / 255, gn = g / 255, bn = b / 255;
  const max = Math.max(rn, gn, bn), min = Math.min(rn, gn, bn);
  const l = (max + min) / 2;
  let h = 0, s = 0;
  if (max !== min) {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case rn: h = ((gn - bn) / d + (gn < bn ? 6 : 0)); break;
      case gn: h = ((bn - rn) / d + 2); break;
      case bn: h = ((rn - gn) / d + 4); break;
    }
    h *= 60;
  }
  return { h, s, l };
}

function hslToCss(h: number, s: number, l: number): string {
  return `hsl(${h.toFixed(1)} ${(s * 100).toFixed(1)}% ${(l * 100).toFixed(1)}%)`;
}

/**
 * ブランド色から 5 つの CSS 変数の値を導出する純関数。パースできない色は null を返す
 * （呼び出し側は既定 branding にフォールバックする）。`isDark` は soft 背景の明度を
 * テーマ依存で決めるため。luminance（BT.601）で前景色を白/黒に振り分ける。
 */
export function deriveSpaceBrandVars(color: string, isDark: boolean): BrandVars | null {
  const rgb = parseColor(color);
  if (!rgb) return null;
  const { h, s, l } = rgbToHsl(rgb);
  // Hover: 12% darker, clamp
  const deepL = Math.max(0.05, l - 0.12);
  // Soft background: light tint in light mode; deep brand tint in dark mode.
  const softL = isDark ? 0.1 : Math.min(0.96, Math.max(0.92, 1 - l * 0.05));
  const softS = isDark ? Math.min(s, 0.5) : Math.min(s, 0.55);
  // Luminance for fg contrast decision (BT.601).
  const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
  const fg = luminance > 0.65 ? '#0f172a' : '#ffffff';

  return {
    '--brand-primary': color,
    '--brand-primary-deep': hslToCss(h, s, deepL),
    '--brand-primary-soft': hslToCss(h, softS, softL),
    '--brand-primary-ring': `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.35)`,
    '--brand-primary-fg': fg,
  };
}
