import { createAccentVariables, type RgbTuple } from "./accent.js";

export type NodedcTheme = "dark" | "light";

export interface NodedcMaterial {
  /** Base fill used by glass panels, application windows and modals. */
  panel?: RgbTuple;
  /** 0–1 alpha for the base glass panel. */
  panelOpacity?: number;
  /** Base fill used by text, range and selection fields. */
  field?: RgbTuple;
  /** 0–1 alpha for field fill. */
  fieldOpacity?: number;
}

export interface ApplyThemeOptions {
  theme?: NodedcTheme;
  accent?: RgbTuple;
  material?: NodedcMaterial;
}

function formatRgb([red, green, blue]: RgbTuple): string {
  return `${red} ${green} ${blue}`;
}

function clampOpacity(value: number): number {
  return Math.max(0, Math.min(1, value));
}

export function applyNodedcTheme(
  target: HTMLElement,
  { theme = "dark", accent, material }: ApplyThemeOptions = {},
): void {
  target.dataset.nodedcTheme = theme;
  target.dataset.nodedcUi = "true";

  if (accent) {
    const variables = createAccentVariables(accent);
    Object.entries(variables).forEach(([property, value]) => {
      target.style.setProperty(property, value);
    });
  }

  if (!material) return;
  if (material.panel) target.style.setProperty("--nodedc-panel-material-rgb", formatRgb(material.panel));
  if (typeof material.panelOpacity === "number" && Number.isFinite(material.panelOpacity)) {
    const opacity = clampOpacity(material.panelOpacity);
    target.style.setProperty("--nodedc-panel-material-opacity", String(opacity));
    target.style.setProperty("--nodedc-panel-material-strong-opacity", String(clampOpacity(opacity + 0.12)));
    target.style.setProperty("--nodedc-panel-material-soft-opacity", String(clampOpacity(Math.max(0.12, opacity - 0.2))));
  }
  if (material.field) target.style.setProperty("--nodedc-field-material-rgb", formatRgb(material.field));
  if (typeof material.fieldOpacity === "number" && Number.isFinite(material.fieldOpacity)) {
    target.style.setProperty("--nodedc-field-material-opacity", String(clampOpacity(material.fieldOpacity)));
  }
}

export function clearNodedcAccent(target: HTMLElement): void {
  target.style.removeProperty("--nodedc-accent-rgb");
  target.style.removeProperty("--nodedc-on-accent-rgb");
}

export function clearNodedcMaterial(target: HTMLElement): void {
  [
    "--nodedc-panel-material-rgb",
    "--nodedc-panel-material-opacity",
    "--nodedc-panel-material-strong-opacity",
    "--nodedc-panel-material-soft-opacity",
    "--nodedc-field-material-rgb",
    "--nodedc-field-material-opacity",
  ].forEach((property) => target.style.removeProperty(property));
}
