// ============================================================================
// «Менеджери» (owner-only): список користувачів CRM, додавання, зміна імені/
// пароля/ролі, Telegram (@username або id) — для mention-сповіщень у топіках.
// Зберігається у newcrm/data/users.json (сід з .env при першій зміні).
// ============================================================================
const { useState: mgUseState, useEffect: mgUseEffect } = React;

async function mgJson(url, opts) {
  const r = await fetch(url, opts);
  let j = {}; try { j = await r.json(); } catch {}
  if (!r.ok) throw new Error(j.error || ("HTTP " + r.status));
  return j;
}
const mgBody = (obj) => ({ headers: { "Content-Type": "application/json" }, body: JSON.stringify(obj) });

const mgInp = { height: 34, padding: "0 11px", borderRadius: 8, border: "1px solid var(--border-default)", background: "var(--bg-raised)", color: "var(--fg-primary)", fontSize: 13, fontFamily: "inherit", outline: "none", width: "100%", boxSizing: "border-box" };
const mgLbl = { fontSize: 10.5, fontWeight: 600, letterSpacing: ".04em", textTransform: "uppercase", color: "var(--fg-muted)", display: "block", marginBottom: 5 };
const mgBtn = (variant) => ({
  height: 34, padding: "0 14px", borderRadius: 8, fontFamily: "inherit", fontSize: 12.5, fontWeight: 500, cursor: "pointer",
  border: "1px solid " + (variant === "primary" ? "var(--accent-ring)" : variant === "danger" ? "rgba(248,113,113,.4)" : "var(--border-default)"),
  background: variant === "primary" ? "var(--accent-soft)" : variant === "danger" ? "rgba(248,113,113,.1)" : "var(--bg-raised)",
  color: variant === "primary" ? "var(--accent)" : variant === "danger" ? "#FCA5A5" : "var(--fg-secondary)",
});

// Дні тижня для рекомендацій вихідних (понеділок закритий — його немає). n = Date.getDay().
const MG_WD = [{ n: 2, l: "Вт" }, { n: 3, l: "Ср" }, { n: 4, l: "Чт" }, { n: 5, l: "Пт" }, { n: 6, l: "Сб" }, { n: 0, l: "Нд" }];

// Форма користувача (нова / редагування). Пароль при редагуванні — лише якщо введено.
function MgUserForm({ initial, onDone, onCancel }) {
  const isNew = !initial;
  const [f, setF] = mgUseState(() => ({
    username: initial ? initial.username : "",
    name: initial ? initial.name : "",
    role: initial ? initial.role : "manager",
    tg: initial ? (initial.tg || "") : "",
    supplier: initial ? (initial.supplier || "") : "",
    password: "",
    dayOffQuota: initial ? (initial.dayOffQuota == null ? 1 : initial.dayOffQuota) : 1,
    dayOffRecs: initial ? (initial.dayOffRecs || []) : [],
  }));
  const set = (k) => (e) => setF(p => ({ ...p, [k]: e.target.value }));
  const [busy, setBusy] = mgUseState(false);
  const [err, setErr] = mgUseState("");
  const save = () => {
    if (busy) return;
    setBusy(true); setErr("");
    const dayOff = { dayOffQuota: Number(f.dayOffQuota) || 0, dayOffRecs: f.dayOffRecs || [] };
    const req = isNew
      ? mgJson("/api/users", { method: "POST", ...mgBody(f) })
      : mgJson("/api/users/" + encodeURIComponent(initial.username), { method: "PUT", ...mgBody({ name: f.name, role: f.role, tg: f.tg, supplier: f.supplier, ...dayOff, ...(f.password.trim() ? { password: f.password } : {}) }) });
    req.then(() => { setBusy(false); onDone(); }).catch(e => { setBusy(false); setErr(e.message); });
  };
  const pill = (active) => ({
    height: 28, padding: "0 12px", borderRadius: 999, fontFamily: "inherit", fontSize: 12, cursor: "pointer",
    border: "1px solid " + (active ? "rgba(110,231,183,.5)" : "var(--border-default)"),
    background: active ? "rgba(110,231,183,.12)" : "var(--bg-raised)", color: active ? "#6EE7B7" : "var(--fg-secondary)",
  });
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12, padding: 14, background: "var(--bg-raised)", border: "1px solid var(--border-subtle)", borderRadius: 12 }}>
      <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-primary)" }}>{isNew ? "Новий менеджер" : "Редагувати: " + initial.name}</div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
        <div><span style={mgLbl}>Логін</span><input style={{ ...mgInp, fontFamily: "var(--font-mono)", opacity: isNew ? 1 : 0.6 }} value={f.username} onChange={set("username")} disabled={!isNew} placeholder="латиниця/цифри"/></div>
        <div><span style={mgLbl}>Імʼя (як у CRM)</span><input style={mgInp} value={f.name} onChange={set("name")} placeholder="Олена"/></div>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
        <div><span style={mgLbl}>{isNew ? "Пароль" : "Новий пароль (порожнє — не міняти)"}</span><input style={{ ...mgInp, fontFamily: "var(--font-mono)" }} type="text" value={f.password} onChange={set("password")} placeholder={isNew ? "мін. 4 символи" : "•••"}/></div>
        <div><span style={mgLbl}>Telegram (@username або id)</span><input style={{ ...mgInp, fontFamily: "var(--font-mono)" }} value={f.tg} onChange={set("tg")} placeholder="@olena_tg"/></div>
      </div>
      <div>
        <span style={mgLbl}>Роль</span>
        <div style={{ display: "flex", gap: 6 }}>
          <button onClick={() => setF(p => ({ ...p, role: "manager" }))} style={pill(f.role === "manager")}>Менеджер</button>
          <button onClick={() => setF(p => ({ ...p, role: "owner" }))} style={pill(f.role === "owner")}>Власник</button>
          <button onClick={() => setF(p => ({ ...p, role: "content" }))} style={pill(f.role === "content")}>Контент-менеджер</button>
          <button onClick={() => setF(p => ({ ...p, role: "supplier" }))} style={pill(f.role === "supplier")}>Постачальник</button>
        </div>
        {f.role === "content" && (
          <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 6 }}>Контент-менеджер бачить у CRM лише вкладки <b>Прайси</b> та <b>Товари</b> (решта розділів прихована).</div>
        )}
      </div>
      {(f.role === "manager" || f.role === "owner") && (
        <div style={{ borderTop: "1px solid var(--border-subtle)", paddingTop: 12 }}>
          <span style={mgLbl}>Вихідних на тиждень (квота)</span>
          <div style={{ display: "flex", gap: 6, marginBottom: 12 }}>
            {[0, 1, 2, 3].map(n => (
              <button key={n} onClick={() => setF(p => ({ ...p, dayOffQuota: n }))} style={pill(Number(f.dayOffQuota) === n)}>{n}</button>
            ))}
          </div>
          <span style={mgLbl}>Рекомендовані дні · клік: —&nbsp;→&nbsp;рекомендувати&nbsp;→&nbsp;фіксувати</span>
          <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
            {MG_WD.map(wd => {
              const cur = (f.dayOffRecs || []).find(r => r.weekday === wd.n);
              const mode = cur ? cur.mode : null;
              const next = mode === null ? "suggest" : mode === "suggest" ? "fixed" : null;
              const color = mode === "fixed" ? "#6EE7B7" : mode === "suggest" ? "#FBBF24" : null;
              const cycle = () => setF(p => {
                const rest = (p.dayOffRecs || []).filter(r => r.weekday !== wd.n);
                return { ...p, dayOffRecs: next ? [...rest, { weekday: wd.n, mode: next }] : rest };
              });
              return (
                <button key={wd.n} onClick={cycle} title={mode === "fixed" ? "Фіксований — авто-бронь" : mode === "suggest" ? "Рекомендація" : "Немає"} style={{
                  minWidth: 52, height: 46, borderRadius: 9, cursor: "pointer", fontFamily: "inherit", padding: "4px 6px",
                  display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 2,
                  border: "1px solid " + (color ? color + "80" : "var(--border-default)"),
                  background: color ? "color-mix(in oklab," + color + " 14%, transparent)" : "var(--bg-raised)",
                  color: color || "var(--fg-secondary)",
                }}>
                  <span style={{ fontSize: 13, fontWeight: 600 }}>{wd.l}</span>
                  <span style={{ fontSize: 9 }}>{mode === "fixed" ? "Фікс." : mode === "suggest" ? "Реком." : "—"}</span>
                </button>
              );
            })}
          </div>
          <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 8, lineHeight: 1.5 }}>
            <b style={{ color: "#FBBF24" }}>Рекомендувати</b> — день підсвітиться, співробітник підтверджує сам. <b style={{ color: "#6EE7B7" }}>Фіксувати</b> — авто-бронюється щотижня; щоб змінити, співробітник надішле тобі запит на підтвердження. Понеділок недоступний для всіх.
          </div>
        </div>
      )}
      {f.role === "supplier" && (
        <div>
          <span style={mgLbl}>Ключ постачальника</span>
          <input style={{ ...mgInp, fontFamily: "var(--font-mono)" }} value={f.supplier} onChange={set("supplier")} placeholder="fkstr"/>
          <div style={{ fontSize: 11, color: "var(--fg-muted)", marginTop: 6 }}>Постачальник бачить ЛИШЕ свій прайс-портал (<span style={{ fontFamily: "var(--font-mono)" }}>/supplier</span>), решта CRM закрита. Для входу через Telegram-мініаплу вкажіть у полі Telegram <b>числовий id</b> його акаунта (не @username).</div>
        </div>
      )}
      <div style={{ fontSize: 11, color: "var(--fg-muted)" }}>Telegram потрібен для пінгів у топіках заявок («постачальник відповів»), а для постачальника — для входу в мініаплу. Вкажіть @username (або числовий Telegram ID).</div>
      {err && <div style={{ fontSize: 12, color: "#FCA5A5" }}>{err}</div>}
      <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
        <button onClick={onCancel} style={mgBtn()}>Скасувати</button>
        <button onClick={save} disabled={busy || (isNew && (!f.username.trim() || !f.password.trim()))} style={mgBtn("primary")}>{busy ? "Зберігаю…" : "Зберегти"}</button>
      </div>
    </div>
  );
}

function Managers({ isMobile }) {
  const [users, setUsers] = mgUseState(null);
  const [err, setErr] = mgUseState("");
  const [editing, setEditing] = mgUseState(null);  // null | "new" | user
  const load = () => mgJson("/api/users").then(j => setUsers(j.users || [])).catch(e => setErr(e.message));
  mgUseEffect(load, []);

  const del = (u) => {
    if (!window.confirm(`Видалити менеджера «${u.name}» (${u.username})? Його сесії перестануть діяти після перелогіну.`)) return;
    setErr("");
    mgJson("/api/users/" + encodeURIComponent(u.username), { method: "DELETE" }).then(load).catch(e => setErr(e.message));
  };

  return (
    <div style={{ flex: 1, overflowY: "auto", padding: isMobile ? "12px 12px 96px" : 24 }}>
      <div style={{ maxWidth: 720, display: "flex", flexDirection: "column", gap: 12 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <Icon name="users" size={16} color="var(--accent)"/>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 14, fontWeight: 600, color: "var(--fg-primary)" }}>Менеджери</div>
            <div style={{ fontSize: 11.5, color: "var(--fg-muted)" }}>Доступи в CRM, паролі, Telegram для сповіщень у топіках</div>
          </div>
          {editing === null && <button onClick={() => setEditing("new")} style={mgBtn("primary")}>+ Додати</button>}
        </div>

        {err && <div style={{ fontSize: 12, color: "#FCA5A5" }}>{err}</div>}
        {editing !== null && (
          <MgUserForm initial={editing === "new" ? null : editing} onDone={() => { setEditing(null); load(); }} onCancel={() => setEditing(null)}/>
        )}

        {users === null && <div style={{ fontSize: 12.5, color: "var(--fg-muted)" }}>Завантаження…</div>}
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {(users || []).map(u => (
            <div key={u.username} style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 14px", background: "var(--bg-panel)", border: "1px solid var(--border-subtle)", borderRadius: 12 }}>
              <Avatar name={u.name} size={36}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                  <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--fg-primary)" }}>{u.name}</span>
                  <span style={{ fontSize: 10, padding: "1px 7px", borderRadius: 999, border: "1px solid var(--border-default)", color: u.role === "owner" ? "#FBBF24" : u.role === "supplier" ? "#7DD3FC" : u.role === "content" ? "#C4B5FD" : "var(--fg-muted)" }}>{u.role === "owner" ? "Власник" : u.role === "supplier" ? "Постачальник" : u.role === "content" ? "Контент-менеджер" : "Менеджер"}</span>
                </div>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--fg-muted)", marginTop: 2 }}>
                  {u.username}{u.role === "supplier" && u.supplier ? " · " + u.supplier : ""}{u.tg ? " · TG: " + u.tg : " · TG не вказано"}
                </div>
              </div>
              <button onClick={() => setEditing(u)} title="Редагувати" style={{ ...mgBtn(), width: 34, padding: 0, display: "inline-flex", alignItems: "center", justifyContent: "center" }}><Icon name="pencil" size={13}/></button>
              <button onClick={() => del(u)} title="Видалити" style={{ ...mgBtn("danger"), width: 34, padding: 0, display: "inline-flex", alignItems: "center", justifyContent: "center" }}><Icon name="trash-2" size={13}/></button>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

window.Managers = Managers;
