// Shared tokens + helpers for CINEV prototype
const CINEV = {
  teal: '#2c5f6f',
  tealDark: '#1f4652',
  tealLight: '#4a8294',
  green: '#8cc152',
  greenDark: '#6ea33d',
  greenLight: '#b6d889',
  bg: '#f6f4ef',
  card: '#ffffff',
  ink: '#1a2a2f',
  inkSoft: '#4a5a60',
  inkMute: '#8a9599',
  line: '#e4ded3',
  lineSoft: '#efeae1',
  warn: '#c96b3a',
  soft: '#f1efe8',
  // Status: mirrors design-system/status.ts (color.status.noShow).
  noShow: { fg: '#c94343', bg: '#f9e6e6', border: '#c94343', borderSoft: '#e3c0c0', accentSoft: '#f5e0e0' },
};

/** Leer: Therapeut:innen kommen aus der API (`therapistApiMap`). Nur noch Fallback für `Avatar` ohne Map. */
const THERAPISTS = [];

/**
 * Koordinations-UI lädt Termine/Patienten nur aus der API (PostgreSQL).
 * `window.__CINEV_LIVE_API === false` schaltet für statische Vorschau (Design-Canvas, Scoping) ab — ohne Demo-Daten im Matrix-Code.
 */
function cinevLiveApi() {
  return typeof window === 'undefined' || window.__CINEV_LIVE_API !== false;
}

// CINEV brand mark — neuron-tree inspired, subtle placeholder for real logo
function CinevMark({ size = 32, mono = false }) {
  const g = mono ? CINEV.teal : CINEV.green;
  const t = mono ? CINEV.teal : CINEV.teal;
  return (
    <svg width={size} height={size} viewBox="0 0 48 48" style={{ display: 'block' }}>
      {/* canopy of neurons */}
      <circle cx="16" cy="14" r="2.2" fill={g}/>
      <circle cx="24" cy="10" r="2.2" fill={g}/>
      <circle cx="32" cy="14" r="2.2" fill={g}/>
      <circle cx="12" cy="20" r="1.8" fill={g}/>
      <circle cx="20" cy="18" r="1.6" fill={g}/>
      <circle cx="28" cy="18" r="1.6" fill={g}/>
      <circle cx="36" cy="20" r="1.8" fill={g}/>
      <circle cx="24" cy="22" r="1.4" fill={g}/>
      <path d="M16 14 L24 10 M24 10 L32 14 M12 20 L16 14 M20 18 L16 14 M20 18 L24 22 M28 18 L24 22 M28 18 L32 14 M36 20 L32 14 M24 10 L24 22"
        stroke={g} strokeWidth="1.2" fill="none" strokeLinecap="round"/>
      {/* trunk */}
      <path d="M24 22 Q24 30 24 40" stroke={t} strokeWidth="2.5" fill="none" strokeLinecap="round"/>
      <path d="M24 30 Q20 34 18 40" stroke={t} strokeWidth="1.8" fill="none" strokeLinecap="round"/>
      <path d="M24 30 Q28 34 30 40" stroke={t} strokeWidth="1.8" fill="none" strokeLinecap="round"/>
    </svg>
  );
}

function hexToRgb(hex) {
  const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(String(hex || ''));
  if (!m) return [138, 149, 153];
  return [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)];
}
function mixRgb(a, b, t) {
  return [
    Math.round(a[0] + (b[0] - a[0]) * t),
    Math.round(a[1] + (b[1] - a[1]) * t),
    Math.round(a[2] + (b[2] - a[2]) * t),
  ];
}
function mixHex(hex, targetHex, t) {
  const rgb = mixRgb(hexToRgb(hex), hexToRgb(targetHex), t);
  return `#${rgb.map((x) => Math.max(0, Math.min(255, x)).toString(16).padStart(2, '0')).join('')}`;
}

/** Therapeut:innen — Pastell-Hintergrund, Initialen in kräftiger Akzentfarbe. */
function Avatar({ therapist, size = 32, therapistApiMap }) {
  const fromApi = therapistApiMap && therapist != null && therapist !== ''
    ? therapistApiMap[String(therapist)]
    : null;
  const t = fromApi || THERAPISTS.find(x => x.id === therapist) || { init: '?', color: CINEV.inkMute };
  const base = t.color || CINEV.inkMute;
  const bg = mixHex(base, '#ffffff', 0.68);
  const border = mixHex(base, '#ffffff', 0.45);
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: bg,
      color: base,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.38, fontWeight: 600, letterSpacing: 0.3,
      flexShrink: 0,
      boxSizing: 'border-box',
      border: `1px solid ${border}`,
    }}>{t.init}</div>
  );
}

const PATIENT_AVATAR_BG = [
  '#2c5f6f', '#1a6b55', '#6b4d8a', '#b3521a', '#246890', '#7a3050', '#305f8a', '#0d7377',
];

function patientAvatarColor(key) {
  const s = String(key ?? '');
  let h = 2166136261;
  for (let i = 0; i < s.length; i++) h = Math.imul(h ^ s.charCodeAt(i), 16777619);
  return PATIENT_AVATAR_BG[Math.abs(h) % PATIENT_AVATAR_BG.length];
}

/** Erster Buchstabe Vorname + erster Buchstabe Nachname (letztes Wort = Nachname). */
function initialsFromPatientName(name) {
  const parts = String(name || '').trim().split(/\s+/).filter(Boolean);
  if (!parts.length) return '?';
  if (parts.length === 1) {
    const w = parts[0];
    return w.length >= 2 ? w.slice(0, 2).toUpperCase() : `${w[0]}?`.toUpperCase();
  }
  const first = parts[0][0] || '';
  const last = parts[parts.length - 1][0] || '';
  return `${first}${last}`.toUpperCase() || '?';
}

/** Patient:innen — kräftige Fläche, weiße Initialen, gleiche Maße wie Avatar (default 32). */
function PatientAvatar({ name, patientKey, size = 32 }) {
  const init = initialsFromPatientName(name);
  const bg = patientAvatarColor(patientKey ?? name ?? init);
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: bg,
      color: '#fff',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: size * 0.38, fontWeight: 700, letterSpacing: 0.2,
      flexShrink: 0,
      boxSizing: 'border-box',
    }}>{init}</div>
  );
}

// Progress ring for sessions (x/12)
function ProgressRing({ done, total, size = 36, stroke = 3.5 }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c - (done / total) * c;
  return (
    <svg width={size} height={size} style={{ display: 'block' }}>
      <circle cx={size/2} cy={size/2} r={r} stroke={CINEV.lineSoft} strokeWidth={stroke} fill="none"/>
      <circle cx={size/2} cy={size/2} r={r} stroke={CINEV.green} strokeWidth={stroke} fill="none"
        strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
        transform={`rotate(-90 ${size/2} ${size/2})`}/>
      <text x="50%" y="50%" textAnchor="middle" dy="0.34em"
        fontSize={size * 0.3} fontWeight="600" fill={CINEV.teal}>{done}</text>
    </svg>
  );
}

// 12-dot session track — now supports variable totals and per-slot statuses
// statuses: undefined uses done-count default; pass array of status strings for per-slot rendering
// Status colors: completed=green, scheduled=grey, no_show=red, rescheduled=amber, next=teal
function SessionDots({ done, total = 12, statuses = null, size = 7, gap = 4 }) {
  // adapt size for long series so 20 dots still fit
  const effSize = total > 14 ? Math.max(5, size - 1) : size;
  const effGap = total > 14 ? Math.max(2, gap - 1) : gap;
  return (
    <div style={{ display: 'flex', gap: effGap, alignItems: 'center', flexWrap: 'nowrap' }}>
      {Array.from({ length: total }).map((_, i) => {
        let bg, border;
        if (statuses && statuses[i]) {
          const s = statuses[i];
          if (s === 'completed') { bg = CINEV.green; border = 'none'; }
          else if (s === 'no_show') { bg = '#c94343'; border = 'none'; }
          else if (s === 'rescheduled') { bg = '#d9a42e'; border = 'none'; }
          else if (s === 'now') { bg = CINEV.teal; border = 'none'; }
          else { bg = 'transparent'; border = `1.5px solid ${CINEV.line}`; }
        } else {
          const isDone = i < done;
          const isNext = i === done;
          bg = isDone ? CINEV.green : isNext ? CINEV.teal : 'transparent';
          border = isDone ? 'none' : `1.5px solid ${isNext ? CINEV.teal : CINEV.line}`;
        }
        return (
          <div key={i} style={{
            width: effSize, height: effSize, borderRadius: '50%',
            background: bg, border, boxSizing: 'border-box', flexShrink: 0,
          }}/>
        );
      })}
    </div>
  );
}

// Semantic colors for appointment type/status — used by calendar matrix and lists
const APPT_COLORS = {
  session_scheduled: { border: CINEV.tealLight, bg: CINEV.card, fg: CINEV.ink },
  session_now: { border: CINEV.teal, bg: CINEV.teal, fg: '#fff' },
  session_done: { border: CINEV.greenDark, bg: '#eaf3df', fg: CINEV.ink },
  makeup: { border: '#d9a42e', bg: '#fdf6e3', fg: CINEV.ink, pattern: true },
  special: { border: '#6b4d8a', bg: '#efe8f4', fg: CINEV.ink },
  no_show: { border: '#c94343', bg: '#f9e6e6', fg: CINEV.ink },
  sick: { border: CINEV.inkMute, bg: '#ececec', fg: CINEV.inkMute, stripe: true },
};

Object.assign(window, { CINEV, THERAPISTS, cinevLiveApi, CinevMark, Avatar, PatientAvatar, ProgressRing, SessionDots, APPT_COLORS });
