export interface SpreadsheetTheme {
  headerBg: string;
  headerText: string;
  cellBg: string;
  border: string;
  text: string;
  textMuted: string;
  selectionBg: string;
  selectionBorder: string;
  dirtyBg: string;
  rowNumBg: string;
  fillHandle: string;
  fixedShadow: string;
  imagePlaceholder: string;
  findMatchBg: string;
  findActiveMatchBg: string;
  findActiveBorder: string;
}

export function getSpreadsheetTheme(isDark: boolean): SpreadsheetTheme {
  if (isDark) {
    return {
      headerBg: '#1f1f1f',
      headerText: 'rgba(255, 255, 255, 0.85)',
      cellBg: '#141414',
      border: '#424242',
      text: 'rgba(255, 255, 255, 0.85)',
      textMuted: 'rgba(255, 255, 255, 0.45)',
      selectionBg: 'rgba(22, 93, 255, 0.25)',
      selectionBorder: '#1668dc',
      dirtyBg: 'rgba(255, 125, 0, 0.2)',
      rowNumBg: '#1a1a1a',
      fillHandle: '#1668dc',
      fixedShadow: 'rgba(0, 0, 0, 0.45)',
      imagePlaceholder: '#303030',
      findMatchBg: 'rgba(255, 212, 0, 0.35)',
      findActiveMatchBg: 'rgba(255, 212, 0, 0.55)',
      findActiveBorder: '#faad14',
    };
  }
  return {
    headerBg: '#f5f7fa',
    headerText: '#1d2129',
    cellBg: '#ffffff',
    border: '#e5e6eb',
    text: '#1d2129',
    textMuted: '#86909c',
    selectionBg: 'rgba(22, 93, 255, 0.08)',
    selectionBorder: '#165dff',
    dirtyBg: 'rgba(255, 125, 0, 0.12)',
    rowNumBg: '#fafafa',
    fillHandle: '#165dff',
    fixedShadow: 'rgba(0, 0, 0, 0.12)',
    imagePlaceholder: '#f2f3f5',
    findMatchBg: '#fff566',
    findActiveMatchBg: '#ffe58f',
    findActiveBorder: '#faad14',
  };
}

export const HEADER_COLOR_PRESETS = [
  '#f0f5ff',
  '#fff7e6',
  '#f6ffed',
  '#fff1f0',
  '#f9f0ff',
  '#e6fffb',
];

function parseHexColor(hex: string): { r: number; g: number; b: number } | null {
  const normalized = hex.trim().replace('#', '');
  if (normalized.length === 3) {
    return {
      r: Number.parseInt(normalized[0]! + normalized[0], 16),
      g: Number.parseInt(normalized[1]! + normalized[1], 16),
      b: Number.parseInt(normalized[2]! + normalized[2], 16),
    };
  }
  if (normalized.length === 6) {
    return {
      r: Number.parseInt(normalized.slice(0, 2), 16),
      g: Number.parseInt(normalized.slice(2, 4), 16),
      b: Number.parseInt(normalized.slice(4, 6), 16),
    };
  }
  return null;
}

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

function hslToHex(h: number, s: number, l: number): string {
  if (s === 0) {
    const v = Math.round(l * 255);
    const hex = v.toString(16).padStart(2, '0');
    return `#${hex}${hex}${hex}`;
  }
  const hue2rgb = (p: number, q: number, t: number) => {
    let tt = t;
    if (tt < 0) tt += 1;
    if (tt > 1) tt -= 1;
    if (tt < 1 / 6) return p + (q - p) * 6 * tt;
    if (tt < 1 / 2) return q;
    if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;
    return p;
  };
  const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
  const p = 2 * l - q;
  const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
  const g = Math.round(hue2rgb(p, q, h) * 255);
  const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
  return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
}

export function resolveHeaderColor(
  color: string | undefined,
  isDark: boolean,
  fallback: string,
): string {
  if (!color) return fallback;
  if (!isDark) return color;

  const rgb = parseHexColor(color);
  if (!rgb) return fallback;

  const { h, s, l } = rgbToHsl(rgb.r, rgb.g, rgb.b);
  const darkL = Math.min(0.28, Math.max(0.16, l * 0.35 + 0.12));
  const darkS = Math.min(0.55, s * 0.75 + 0.08);
  return hslToHex(h, darkS, darkL);
}
