/* ui.jsx — zdieľané UI prvky pre helpdesk */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------- ikony (Fluent-style line icons) ---------- */
const Icon = ({ name, size = 18, style }) => {
  const paths = {
    search: "M10 4a6 6 0 0 1 4.74 9.68l4.79 4.79-1.06 1.06-4.79-4.79A6 6 0 1 1 10 4Zm0 1.5a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9Z",
    refresh: "M12 4a8 8 0 1 1-7.6 5.5l1.43.47A6.5 6.5 0 1 0 12 5.5V8L8 4.5 12 1Z",
    send: "M3 11 20 3l-7 17-2.5-6.5L3 11Z",
    note: "M5 3h11l4 4v14H5V3Zm10 1.5V8h3.5L15 4.5ZM8 11h8v1.5H8V11Zm0 3h8v1.5H8V14Z",
    attach: "M8 7v8a3 3 0 0 0 6 0V6a4.5 4.5 0 0 0-9 0v9a6 6 0 0 0 12 0V7h-1.5v8a4.5 4.5 0 0 1-9 0V6a3 3 0 0 1 6 0v9a1.5 1.5 0 0 1-3 0V7H8Z",
    chart: "M4 20V4h1.5v14.5H20V20H4Zm3-3V9h3v8H7Zm5 0V5h3v12h-3Zm5 0v-5h3v5h-3Z",
    settings: "M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm0 1.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM10.6 2l-.4 2.2a8 8 0 0 0-1.7 1l-2.1-.8L4 7.9l1.7 1.4a8 8 0 0 0 0 2l-1.7 1.4 2.4 3.5 2.1-.8a8 8 0 0 0 1.7 1l.4 2.2h2.8l.4-2.2a8 8 0 0 0 1.7-1l2.1.8 2.4-3.5-1.7-1.4a8 8 0 0 0 0-2L20 7.9l-2.4-3.5-2.1.8a8 8 0 0 0-1.7-1L13.4 2h-2.8Z",
    clock: "M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 1.5a7.5 7.5 0 1 1 0 15 7.5 7.5 0 0 1 0-15ZM11.25 7h1.5v5.31l3.4 2 -.76 1.3-4.14-2.43V7Z",
    person: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm0-6.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM4 20a8 8 0 0 1 16 0v.5H4V20Zm1.6-1h12.8a6.5 6.5 0 0 0-12.8 0Z",
    mail: "M3 5h18v14H3V5Zm1.7 1.5 7.3 5.2 7.3-5.2H4.7ZM19.5 8 12 13.3 4.5 8v9.5h15V8Z",
    chevron: "M8.5 5 16 12l-7.5 7-1-1L13.6 12 7.5 6l1-1Z",
    chevronDown: "M5 8.5 12 16l7-7.5-1-1L12 13.6 6 7.5l-1 1Z",
    warning: "M12 3 22 20H2L12 3Zm0 3.2L4.7 18.5h14.6L12 6.2ZM11.25 10h1.5v4h-1.5v-4Zm0 5h1.5v1.5h-1.5V15Z",
    check: "M9.5 16.2 5.3 12l-1.1 1.1 5.3 5.3L20.8 7 19.7 6 9.5 16.2Z",
    checkCircle: "M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 1.5a7.5 7.5 0 1 1 0 15 7.5 7.5 0 0 1 0-15Zm-1.1 10.3-2.4-2.4-1.1 1.1 3.5 3.5 5.7-5.7-1.1-1.1-4.6 4.6Z",
    close: "M6 5 5 6l6 6-6 6 1 1 6-6 6 6 1-1-6-6 6-6-1-1-6 6-6-6Z",
    reopen: "M12 5V2L8 6l4 4V7a5 5 0 1 1-5 5H5.5A6.5 6.5 0 1 0 12 5Z",
    hand: "M7 11V5.5a1.5 1.5 0 0 1 3 0V10h.5V4.5a1.5 1.5 0 0 1 3 0V10h.5V6a1.5 1.5 0 0 1 3 0v7a6 6 0 0 1-6 6h-1a5 5 0 0 1-4.3-2.5l-2.4-4 .3-.3a1.6 1.6 0 0 1 2 .2L7 14V11Z",
    assign: "M9 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm0-6.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5ZM2 19.5a7 7 0 0 1 13.3-3h-1.8A5.5 5.5 0 0 0 3.5 19.5V20H2v-.5ZM18 13h1.5v3H22v1.5h-2.5V20H18v-2.5h-2.5V16H18v-3Z",
    paperclip: "M16.5 6.5 8 15a2.5 2.5 0 0 0 3.5 3.5l8-8a4.5 4.5 0 0 0-6.4-6.4l-8.3 8.3a6.5 6.5 0 0 0 9.2 9.2l.7-.7-1-1-.7.7a5 5 0 0 1-7-7l8.2-8.3a3 3 0 1 1 4.3 4.3l-8 8a1 1 0 0 1-1.4-1.4l8.5-8.5-1-1Z",
    file: "M5 3h9l5 5v13H5V3Zm8 1.5V9h4.5L13 4.5ZM7 5v14h10V10.5h-5.5V5H7Z",
    image: "M4 5h16v14H4V5Zm1.5 1.5v8.4l3.5-3.5 2.5 2.5 3.5-3.5 4 4V6.5h-17ZM8 9.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z",
    sun: "M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10Zm0 1.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7ZM12 1v3h-1V1h1Zm0 19v3h-1v-3h1ZM1 11h3v1H1v-1Zm19 0h3v1h-3v-1ZM4.2 4.2l2.1 2.1-.7.7-2.1-2.1.7-.7Zm13.5 13.5 2.1 2.1-.7.7-2.1-2.1.7-.7ZM19.8 4.2l.7.7-2.1 2.1-.7-.7 2.1-2.1ZM6.3 17.7l.7.7-2.1 2.1-.7-.7 2.1-2.1Z",
    moon: "M13 3a9 9 0 1 0 8 13 7.5 7.5 0 0 1-8-13Zm-1.6 1.9A7.5 7.5 0 1 0 19 15.6 9 9 0 0 1 11.4 4.9Z",
    filter: "M3 5h18v1.6l-7 7V21l-4-2v-5.4l-7-7V5Zm2.2 1.6 6.3 6.3v4.4l1-.5V13l6.3-6.3H5.2Z",
    grid: "M4 4h7v7H4V4Zm9 0h7v7h-7V4ZM4 13h7v7H4v-7Zm9 0h7v7h-7v-7Z",
    dot: "M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Z",
    sort: "M7 4 3.5 8H6v8h2V8h2.5L7 4Zm10 16 3.5-4H18V8h-2v8h-2.5L17 20Z",
    plus: "M11.25 4h1.5v7.25H20v1.5h-7.25V20h-1.5v-7.25H4v-1.5h7.25V4Z",
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" style={style} aria-hidden="true">
      <path d={paths[name] || ""} />
    </svg>
  );
};

/* ---------- avatar ---------- */
const Avatar = ({ meno, farba, size = 28, src }) => {
  const ini = (meno || "?").split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: "50%", flex: "0 0 auto",
      background: farba || "var(--accent)", color: "#fff",
      display: "flex", alignItems: "center", justifyContent: "center",
      fontSize: size * 0.4, fontWeight: 600, letterSpacing: ".2px",
      boxShadow: "inset 0 0 0 1px rgba(255,255,255,.15)", userSelect: "none",
    }} title={meno}>{ini}</div>
  );
};

/* ---------- farby stavov a priorít ---------- */
const STAV_FARBA = {
  "Nový": "var(--c-novy)", "Priradený": "var(--c-prirad)", "V riešení": "var(--c-riesi)",
  "Čaká na zákazníka": "var(--c-caka)", "Vyriešený": "var(--c-vyrie)", "Zatvorený": "var(--c-zatv)",
};
const PRIO_FARBA = {
  "Nízka": "var(--p-nizka)", "Stredná": "var(--p-stred)", "Vysoká": "var(--p-vysoka)", "Kritická": "var(--p-krit)",
};

const StatusDot = ({ stav, size = 8 }) => (
  <span style={{ width: size, height: size, borderRadius: "50%", background: STAV_FARBA[stav], flex: "0 0 auto", display: "inline-block" }} />
);

const StatusBadge = ({ stav }) => (
  <span style={{
    display: "inline-flex", alignItems: "center", gap: 6,
    padding: "3px 9px 3px 8px", borderRadius: 999, fontSize: 12, fontWeight: 600,
    color: STAV_FARBA[stav], background: "color-mix(in srgb, " + (STAV_FARBA[stav]) + " 12%, transparent)",
    border: "1px solid color-mix(in srgb, " + (STAV_FARBA[stav]) + " 26%, transparent)", whiteSpace: "nowrap",
  }}>
    <StatusDot stav={stav} size={7} />{stav}
  </span>
);

const PriorityBadge = ({ priorita, small }) => {
  const c = PRIO_FARBA[priorita];
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5,
      padding: small ? "1px 7px" : "3px 9px", borderRadius: 999, fontSize: small ? 11 : 12, fontWeight: 600,
      color: c, background: "color-mix(in srgb, " + c + " 13%, transparent)", whiteSpace: "nowrap",
    }}>
      <span style={{ width: 6, height: 6, borderRadius: 2, background: c, transform: "rotate(45deg)" }} />
      {priorita}
    </span>
  );
};

/* ---------- formátovače času ---------- */
function fmtRelative(ts) {
  const diff = Date.now() - ts;
  const m = Math.floor(diff / 60000);
  if (m < 1) return "práve teraz";
  if (m < 60) return "pred " + m + " min";
  const h = Math.floor(m / 60);
  if (h < 24) return "pred " + h + " h";
  const d = Math.floor(h / 24);
  if (d < 7) return "pred " + d + " d";
  return new Date(ts).toLocaleDateString("sk-SK", { day: "numeric", month: "short" });
}
function fmtDateTime(ts) {
  return new Date(ts).toLocaleString("sk-SK", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" });
}
function fmtCountdown(ms) {
  const neg = ms < 0;
  let s = Math.abs(Math.floor(ms / 1000));
  const d = Math.floor(s / 86400); s -= d * 86400;
  const h = Math.floor(s / 3600); s -= h * 3600;
  const m = Math.floor(s / 60); s -= m * 60;
  const pad = (n) => String(n).padStart(2, "0");
  const body = (d > 0 ? d + "d " : "") + pad(h) + "h " + pad(m) + "m " + pad(s) + "s";
  return (neg ? "−" : "") + body;
}

/* tlačidlo (Fluent) */
const Btn = ({ kind = "default", icon, children, onClick, disabled, full, title, size = "md" }) => {
  const [hover, setHover] = useState(false);
  const [press, setPress] = useState(false);
  const pads = size === "sm" ? "5px 10px" : "8px 14px";
  const base = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 7,
    padding: pads, borderRadius: "var(--radius-sm)", fontSize: size === "sm" ? 13 : 14, fontWeight: 600,
    border: "1px solid transparent", transition: "background .12s, border-color .12s, box-shadow .12s, transform .05s",
    width: full ? "100%" : "auto", whiteSpace: "nowrap", lineHeight: 1.2,
    transform: press ? "translateY(.5px)" : "none", opacity: disabled ? 0.5 : 1,
    pointerEvents: disabled ? "none" : "auto",
  };
  const kinds = {
    primary: { background: hover ? "var(--accent-hover)" : "var(--accent)", color: "var(--accent-on)" },
    green: { background: hover ? "var(--green-hover)" : "var(--green)", color: "#fff" },
    danger: { background: hover ? "var(--red-hover)" : "var(--red)", color: "#fff" },
    default: { background: hover ? "var(--surface-3)" : "var(--surface)", color: "var(--text)", borderColor: "var(--stroke-strong)" },
    subtle: { background: hover ? "var(--surface-3)" : "transparent", color: "var(--text)" },
    ghostDanger: { background: hover ? "var(--danger-tint)" : "transparent", color: "var(--red)", borderColor: hover ? "transparent" : "var(--stroke)" },
  };
  return (
    <button title={title} onClick={onClick} disabled={disabled}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }}
      onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}
      style={{ ...base, ...kinds[kind] }}>
      {icon && <Icon name={icon} size={size === "sm" ? 15 : 16} />}
      {children}
    </button>
  );
};

/* ikonové tlačidlo */
const IconBtn = ({ name, onClick, title, active, size = 18, badge }) => {
  const [hover, setHover] = useState(false);
  return (
    <button title={title} onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        position: "relative", width: 34, height: 34, borderRadius: "var(--radius-sm)", border: "none",
        background: active ? "var(--accent-tint)" : hover ? "var(--surface-3)" : "transparent",
        color: active ? "var(--accent)" : "var(--text-2)", display: "inline-flex", alignItems: "center", justifyContent: "center",
        transition: "background .12s, color .12s",
      }}>
      <Icon name={name} size={size} />
      {badge != null && badge > 0 && (
        <span style={{ position: "absolute", top: 3, right: 3, minWidth: 15, height: 15, padding: "0 3px", borderRadius: 8,
          background: "var(--red)", color: "#fff", fontSize: 10, fontWeight: 700, display: "flex", alignItems: "center", justifyContent: "center" }}>{badge}</span>
      )}
    </button>
  );
};

const fileIcon = (typ) => (typ === "png" || typ === "jpg" || typ === "jpeg" || typ === "image") ? "image" : "file";

Object.assign(window, {
  useState, useEffect, useRef, useMemo, useCallback,
  Icon, Avatar, StatusDot, StatusBadge, PriorityBadge,
  STAV_FARBA, PRIO_FARBA, fmtRelative, fmtDateTime, fmtCountdown,
  Btn, IconBtn, fileIcon,
});
