/**
 * Shared pastel palette for treatment types, prosthesis types, and dashboard charts.
 * Treatment and prosthesis each have dedicated hex maps — prosthesis colors are unique
 * within the prosthesis catalog (no duplicate swatches on charts or badges).
 */

export const TREATMENT_TYPE_COLORS: Record<string, string> = {
  restoration: '#fed7aa',
  specialized_restoration: '#fdba74',
  radiography: '#cbd5e1',
  endo: '#fecaca',
  surgery: '#fca5a5',
  prosthesis: '#c4b5fd',
  implant: '#a5b4fc',
  orthodontics: '#93c5fd',
  perio: '#86efac',
  pediatrics: '#fde68a',
  extraction: '#f9a8d4',
  clinic_visit: '#bae6fd',
  continue_treatment: '#99f6e4',
};

/** Category tiles — heaviest (darkest) pastel of each family; leaves lighten from here. */
export const PROSTHESIS_CATEGORY_COLORS: Record<string, string> = {
  crown: '#e6c84f',
  indirect: '#f59e4c',
  implant: '#38bdf8',
  post_core: '#a8a29e',
  removable: '#a78bfa',
  appliance: '#d8b4fe',
  digital: '#f472b6',
};

function hexToRgbChannels(hex: string): [number, number, number] | null {
  const raw = hex.replace('#', '').trim();
  if (raw.length !== 6) return null;
  const n = Number.parseInt(raw, 16);
  if (Number.isNaN(n)) return null;
  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}

function rgbToHslChannels(r: number, g: number, b: number): [number, number, number] {
  const rr = r / 255;
  const gg = g / 255;
  const bb = b / 255;
  const max = Math.max(rr, gg, bb);
  const min = Math.min(rr, gg, bb);
  const l = (max + min) / 2;
  if (max === min) return [0, 0, l];
  const d = max - min;
  const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  let h = 0;
  if (max === rr) h = ((gg - bb) / d + (gg < bb ? 6 : 0)) / 6;
  else if (max === gg) h = ((bb - rr) / d + 2) / 6;
  else h = ((rr - gg) / d + 4) / 6;
  return [h, s, l];
}

function hslToHexChannels(h: number, s: number, l: number): string {
  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, g, b].map((c) => c.toString(16).padStart(2, '0')).join('')}`;
}

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

/** Same-hue sibling of a category pastel. Index 0 is the parent (heaviest); higher indices only lighten. */
export function prosthesisFamilyTone(parentHex: string, siblingIndex: number): string {
  if (siblingIndex <= 0) return parentHex;
  const rgb = hexToRgbChannels(parentHex);
  if (!rgb) return parentHex;
  const [h, s, l] = rgbToHslChannels(rgb[0], rgb[1], rgb[2]);
  const nextL = clamp01(Math.min(0.9, l + siblingIndex * 0.038));
  const nextS = clamp01(s - siblingIndex * 0.025);
  return hslToHexChannels(h, nextS, nextL);
}

export function prosthesisCategoryFamilyColor(category: string, siblingIndex = 0): string {
  const parent = PROSTHESIS_CATEGORY_COLORS[category] ?? '#e2e8f0';
  return prosthesisFamilyTone(parent, siblingIndex);
}

/** Dedicated prosthesis palette — family tones (legacy map kept as fallback). */
export const PROSTHESIS_TYPE_COLORS: Record<string, string> = {
  pfm_crown: prosthesisCategoryFamilyColor('crown', 1),
  pfz_crown: prosthesisCategoryFamilyColor('crown', 2),
  monolithic_zirconia: prosthesisCategoryFamilyColor('crown', 3),
  glass_ceramic_crown: prosthesisCategoryFamilyColor('crown', 4),
  full_metal_crown: prosthesisCategoryFamilyColor('crown', 5),
  temporary_resin_crown: prosthesisCategoryFamilyColor('crown', 6),
  pmma: prosthesisCategoryFamilyColor('crown', 7),
  peek_crown: prosthesisCategoryFamilyColor('crown', 8),
  press_ceramic: prosthesisCategoryFamilyColor('crown', 9),
  veneer_zirconia: prosthesisCategoryFamilyColor('indirect', 1),
  veneer_ips_press: prosthesisCategoryFamilyColor('indirect', 2),
  veneer_ips_cad: prosthesisCategoryFamilyColor('indirect', 3),
  zirconia_overlay: prosthesisCategoryFamilyColor('indirect', 4),
  ips_overlay: prosthesisCategoryFamilyColor('indirect', 5),
  veneer_full_contour: prosthesisCategoryFamilyColor('indirect', 1),
  veneer_layered: prosthesisCategoryFamilyColor('indirect', 2),
  inlay_full_contour: prosthesisCategoryFamilyColor('indirect', 3),
  inlay_layered: prosthesisCategoryFamilyColor('indirect', 4),
  onlay_full_contour: prosthesisCategoryFamilyColor('indirect', 5),
  onlay_layered: prosthesisCategoryFamilyColor('indirect', 6),
  overlay_full_contour: prosthesisCategoryFamilyColor('indirect', 7),
  overlay_layered: prosthesisCategoryFamilyColor('indirect', 8),
  customized_abutment: prosthesisCategoryFamilyColor('implant', 1),
  prefabricated_abutment: prosthesisCategoryFamilyColor('implant', 2),
  ti_base_abutment: prosthesisCategoryFamilyColor('implant', 3),
  multi_unit_abutment: prosthesisCategoryFamilyColor('implant', 4),
  zirconia_abutment: prosthesisCategoryFamilyColor('implant', 5),
  screw_retained: prosthesisCategoryFamilyColor('implant', 6),
  cast_post_core: prosthesisCategoryFamilyColor('post_core', 1),
  fiber_post_core: prosthesisCategoryFamilyColor('post_core', 2),
  complete_denture: prosthesisCategoryFamilyColor('removable', 1),
  partial_denture: prosthesisCategoryFamilyColor('removable', 2),
  overdenture: prosthesisCategoryFamilyColor('removable', 3),
  night_guard_soft: prosthesisCategoryFamilyColor('appliance', 1),
  night_guard_hard: prosthesisCategoryFamilyColor('appliance', 2),
  night_guard_dual: prosthesisCategoryFamilyColor('appliance', 3),
  bleaching_tray: prosthesisCategoryFamilyColor('appliance', 4),
  clear_aligner: prosthesisCategoryFamilyColor('appliance', 5),
  soft_structure: prosthesisCategoryFamilyColor('appliance', 6),
  smile_design: prosthesisCategoryFamilyColor('digital', 1),
  mockup: prosthesisCategoryFamilyColor('digital', 2),
  surgical_guide: prosthesisCategoryFamilyColor('digital', 3),
};

export const CATALOG_FALLBACK_COLORS = [
  '#ddd6fe',
  '#fed7aa',
  '#fecaca',
  '#bae6fd',
  '#d9f99d',
  '#fbcfe8',
] as const;

/** Fallback rotation for unknown prosthesis codes — drawn from the prosthesis palette. */
export const PROSTHESIS_FALLBACK_COLORS: readonly string[] = [
  ...new Set(Object.values(PROSTHESIS_TYPE_COLORS)),
];

/** Ordered palette for charts and rotating unknown treatment catalog codes. */
export const CATALOG_PALETTE_COLORS: readonly string[] = [
  '#fed7aa',
  '#fdba74',
  '#cbd5e1',
  '#fecaca',
  '#fca5a5',
  '#c4b5fd',
  '#a5b4fc',
  '#93c5fd',
  '#86efac',
  '#fde68a',
  '#f9a8d4',
  '#bae6fd',
  '#99f6e4',
  '#ddd6fe',
  '#d9f99d',
  '#fbcfe8',
  ...PROSTHESIS_FALLBACK_COLORS.filter(
    (color) =>
      ![
        '#fed7aa',
        '#fdba74',
        '#bae6fd',
        '#f9a8d4',
        '#ddd6fe',
        '#fbcfe8',
        '#a5b4fc',
      ].includes(color),
  ),
];

export function resolveCatalogTypeColor(
  code: string,
  colorMap: Record<string, string>,
  index = 0,
  fallbackColors: readonly string[] = CATALOG_FALLBACK_COLORS,
): string {
  return colorMap[code] ?? fallbackColors[index % fallbackColors.length];
}
