/**
 * Color Utilities for Tag Visualization
 *
 * Provides utilities for blending multiple tag colors and creating
 * visual indicators for collections with multiple tags.
 */

/**
 * Convert hex color to RGB
 * @param {string} hex - Hex color code (e.g., "#FF5733")
 * @returns {{r: number, g: number, b: number}} RGB object
 */
function hexToRgb(hex) {
  // Remove # if present
  hex = hex.replace(/^#/, '');

  // Parse hex values
  const bigint = parseInt(hex, 16);
  const r = (bigint >> 16) & 255;
  const g = (bigint >> 8) & 255;
  const b = bigint & 255;

  return { r, g, b };
}

/**
 * Convert RGB to hex color
 * @param {number} r - Red (0-255)
 * @param {number} g - Green (0-255)
 * @param {number} b - Blue (0-255)
 * @returns {string} Hex color code
 */
function rgbToHex(r, g, b) {
  return "#" + ((1 << 24) + (Math.round(r) << 16) + (Math.round(g) << 8) + Math.round(b))
    .toString(16)
    .slice(1)
    .toUpperCase();
}

/**
 * Blend multiple colors using average RGB values
 * @param {string[]} colors - Array of hex color codes
 * @returns {string} Blended hex color
 */
export function blendColors(colors) {
  if (!colors || colors.length === 0) {
    return '#9CA3AF'; // Default gray color
  }

  if (colors.length === 1) {
    return colors[0];
  }

  // Convert all colors to RGB
  const rgbColors = colors.map(hexToRgb);

  // Calculate average RGB values
  const avgR = rgbColors.reduce((sum, c) => sum + c.r, 0) / rgbColors.length;
  const avgG = rgbColors.reduce((sum, c) => sum + c.g, 0) / rgbColors.length;
  const avgB = rgbColors.reduce((sum, c) => sum + c.b, 0) / rgbColors.length;

  // Convert back to hex
  return rgbToHex(avgR, avgG, avgB);
}

/**
 * Create a gradient string from multiple colors
 * @param {string[]} colors - Array of hex color codes
 * @returns {string} CSS linear gradient string
 */
export function createGradientFromColors(colors) {
  if (!colors || colors.length === 0) {
    return 'linear-gradient(135deg, #9CA3AF, #6B7280)';
  }

  if (colors.length === 1) {
    const color = colors[0];
    // Create a subtle gradient with the same color (lighter to darker)
    return `linear-gradient(135deg, ${color}E6, ${color})`;
  }

  if (colors.length === 2) {
    return `linear-gradient(135deg, ${colors[0]}, ${colors[1]})`;
  }

  // For 3+ colors, create evenly spaced gradient stops
  const stops = colors.map((color, index) => {
    const percentage = (index / (colors.length - 1)) * 100;
    return `${color} ${percentage}%`;
  }).join(', ');

  return `linear-gradient(135deg, ${stops})`;
}

/**
 * Lighten a color by a percentage
 * @param {string} color - Hex color code
 * @param {number} percent - Percentage to lighten (0-100)
 * @returns {string} Lightened hex color
 */
export function lightenColor(color, percent) {
  const rgb = hexToRgb(color);
  const factor = 1 + (percent / 100);

  const r = Math.min(255, rgb.r * factor);
  const g = Math.min(255, rgb.g * factor);
  const b = Math.min(255, rgb.b * factor);

  return rgbToHex(r, g, b);
}

/**
 * Darken a color by a percentage
 * @param {string} color - Hex color code
 * @param {number} percent - Percentage to darken (0-100)
 * @returns {string} Darkened hex color
 */
export function darkenColor(color, percent) {
  const rgb = hexToRgb(color);
  const factor = 1 - (percent / 100);

  const r = Math.max(0, rgb.r * factor);
  const g = Math.max(0, rgb.g * factor);
  const b = Math.max(0, rgb.b * factor);

  return rgbToHex(r, g, b);
}

/**
 * Add opacity to a hex color (returns rgba)
 * @param {string} color - Hex color code
 * @param {number} opacity - Opacity (0-1)
 * @returns {string} RGBA color string
 */
export function addOpacity(color, opacity) {
  const rgb = hexToRgb(color);
  return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;
}

/**
 * Get contrasting text color (black or white) for a background color
 * @param {string} bgColor - Background hex color
 * @returns {string} '#000000' or '#FFFFFF'
 */
export function getContrastColor(bgColor) {
  const rgb = hexToRgb(bgColor);

  // Calculate relative luminance
  const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;

  // Return black for light backgrounds, white for dark backgrounds
  return luminance > 0.5 ? '#000000' : '#FFFFFF';
}
