const { useState, useEffect, useMemo, useCallback } = React;

// ---------- api helper ----------
async function api(path, options = {}) {
  const res = await fetch(path, {
    method: options.method || "GET",
    headers: options.body ? { "Content-Type": "application/json" } : undefined,
    body: options.body ? JSON.stringify(options.body) : undefined,
    credentials: "same-origin",
  });
  if (!res.ok) {
    let msg = "Klaida";
    try {
      const j = await res.json();
      msg = j.error || msg;
    } catch {}
    throw new Error(msg);
  }
  return res.json();
}

// ---------- helpers ----------
const pad = (n) => String(n).padStart(2, "0");
function genSlots(startHour, endHour, intervalMin) {
  const out = [];
  for (let m = startHour * 60; m < endHour * 60; m += intervalMin) {
    out.push(`${pad(Math.floor(m / 60))}:${pad(m % 60)}`);
  }
  return out;
}
function slotDate(dateStr, timeStr) {
  return new Date(`${dateStr}T${timeStr}:00`);
}
function todayStr() {
  const d = new Date();
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}

const ROLE_META = {
  admin: { label: "Administratorius", emoji: "🛡️", color: "#7C3AED" },
  manager: { label: "Vadas", emoji: "💼", color: "#2563EB" },
  user: { label: "Agentas", emoji: "👤", color: "#059669" },
};

// ==================== ROOT ====================
function Root() {
  const [me, setMe] = useState(undefined); // undefined = kraunama, null = neprisijungęs
  const [loginError, setLoginError] = useState("");

  useEffect(() => {
    api("/api/me")
      .then(setMe)
      .catch(() => setMe(null));
  }, []);

  async function handleLogin(username, password) {
    setLoginError("");
    try {
      const u = await api("/api/login", { method: "POST", body: { username, password } });
      setMe(u);
    } catch (e) {
      setLoginError(e.message);
    }
  }

  async function handleLogout() {
    await api("/api/logout", { method: "POST" });
    setMe(null);
  }

  if (me === undefined) {
    return <div style={{ padding: 40, fontFamily: "sans-serif", color: "#6B7280" }}>Kraunama…</div>;
  }
  if (me === null) {
    return <LoginScreen onLogin={handleLogin} error={loginError} />;
  }
  return <MainApp me={me} onLogout={handleLogout} />;
}

function LoginScreen({ onLogin, error }) {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [submitting, setSubmitting] = useState(false);

  async function submit(e) {
    e.preventDefault();
    if (!username || !password) return;
    setSubmitting(true);
    await onLogin(username, password);
    setSubmitting(false);
  }

  return (
    <div
      style={{
        minHeight: "100vh",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        background: "#0F172A",
      }}
    >
      <form
        onSubmit={submit}
        style={{
          background: "#fff",
          borderRadius: 14,
          padding: 32,
          width: 340,
          boxShadow: "0 20px 60px rgba(0,0,0,0.35)",
        }}
      >
        <div style={{ fontWeight: 800, fontSize: 18, marginBottom: 4 }}>Publikavimo grafikas</div>
        <div style={{ fontSize: 13, color: "#6B7280", marginBottom: 20 }}>Prisijunkite prie sistemos</div>

        <label style={fieldLabel}>Prisijungimo vardas</label>
        <input
          autoFocus
          value={username}
          onChange={(e) => setUsername(e.target.value)}
          style={inputStyle}
        />
        <label style={{ ...fieldLabel, marginTop: 12 }}>Slaptažodis</label>
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          style={inputStyle}
        />

        {error && (
          <div style={{ color: "#DC2626", fontSize: 13, marginTop: 12 }}>{error}</div>
        )}

        <button
          type="submit"
          disabled={submitting}
          style={{ ...primaryBtn, width: "100%", justifyContent: "center", marginTop: 20, padding: "10px 0" }}
        >
          {submitting ? "Jungiamasi…" : "Prisijungti"}
        </button>
      </form>
    </div>
  );
}

// ==================== MAIN APP ====================
function MainApp({ me, onLogout }) {
  const role = me.role;
  const currentUserId = me.id;

  const [users, setUsers] = useState([]);
  const [series, setSeries] = useState([]);
  const [products, setProducts] = useState([]);
  const [assignments, setAssignments] = useState([]);
  const [intervalMin, setIntervalMin] = useState(10);

  const [date, setDate] = useState(todayStr());
  const [selectedSeriesId, setSelectedSeriesId] = useState(null);
  const [tab, setTab] = useState("matrix");
  const [tick, setTick] = useState(Date.now());
  const [errorMsg, setErrorMsg] = useState("");

  const applyState = (s) => {
    setUsers(s.users);
    setSeries(s.series);
    setProducts(s.products);
    setAssignments(s.assignments);
    setIntervalMin(s.intervalMin);
  };

  const refresh = useCallback(() => {
    api("/api/state")
      .then(applyState)
      .catch((e) => setErrorMsg(e.message));
  }, []);

  useEffect(() => {
    refresh();
    const poll = setInterval(refresh, 4000); // bendras vaizdas - periodiškai atsinaujina visiems
    const clock = setInterval(() => setTick(Date.now()), 1000);
    return () => {
      clearInterval(poll);
      clearInterval(clock);
    };
  }, [refresh]);

  useEffect(() => {
    if (!selectedSeriesId && series.length > 0) setSelectedSeriesId(series[0].id);
  }, [series, selectedSeriesId]);

  const now = tick;
  const slots = useMemo(() => genSlots(0, 24, intervalMin), [intervalMin]);
  const matrixUsers = users.filter((u) => u.role === "user");
  const seriesById = useMemo(() => Object.fromEntries(series.map((s) => [s.id, s])), [series]);
  const productsById = useMemo(() => {
    const map = {};
    for (const p of products) {
      const srs = seriesById[p.seriesId];
      map[p.id] = { ...p, code: srs ? `${srs.code}-${pad(p.seq, 2)}` : "??" };
    }
    return map;
  }, [products, seriesById]);

  function findAssignment(userId, time) {
    return assignments.find((a) => a.userId === userId && a.time === time && a.date === date);
  }

  function computeStatus(a) {
    if (!a)
      return { state: "empty", published: false, late: false, future: false, ready: false, locked: false };
    const slotStart = slotDate(a.date, a.time).getTime();
    const due = slotStart + intervalMin * 60000;
    const locked = now >= due;
    const late = locked && !a.published;
    const future = now < slotStart;
    return { state: "assigned", published: !!a.published, late, future, ready: !!a.ready, locked };
  }

  async function handleAssignClick(userId, time) {
    if (!selectedSeriesId) return;
    const existing = findAssignment(userId, time);
    if (existing) return;
    try {
      const s = await api("/api/assign", { method: "POST", body: { userId, date, time, seriesId: selectedSeriesId } });
      applyState(s);
    } catch (e) {
      setErrorMsg(e.message);
    }
  }
  async function handleIncrement(productId) {
    try {
      applyState(await api(`/api/products/${productId}/inc`, { method: "POST" }));
    } catch (e) {
      setErrorMsg(e.message);
    }
  }
  async function handleDecrement(productId) {
    try {
      applyState(await api(`/api/products/${productId}/dec`, { method: "POST" }));
    } catch (e) {
      setErrorMsg(e.message);
    }
  }
  async function handleDeleteAssignment(assignmentId) {
    try {
      applyState(await api(`/api/assignments/${assignmentId}`, { method: "DELETE" }));
    } catch (e) {
      setErrorMsg(e.message);
    }
  }
  async function handleAgentAction(assignmentId) {
    try {
      applyState(await api(`/api/assignments/${assignmentId}/agent-action`, { method: "POST" }));
    } catch (e) {
      setErrorMsg(e.message);
    }
  }

  function onCellClick(userId, time) {
    if (role === "manager" || role === "admin") {
      handleAssignClick(userId, time);
    } else if (role === "user" && userId === currentUserId) {
      const a = findAssignment(userId, time);
      if (a) handleAgentAction(a.id);
    }
  }

  // ---- admin: vartotojai ----
  async function addUser({ name, username, password, role }) {
    applyState(await api("/api/users", { method: "POST", body: { name, username, password, role } }));
  }
  async function removeUser(id) {
    applyState(await api(`/api/users/${id}`, { method: "DELETE" }));
  }
  async function changeUserRole(id, role) {
    applyState(await api(`/api/users/${id}/role`, { method: "PUT", body: { role } }));
  }
  async function resetPassword(id, password) {
    await api(`/api/users/${id}/password`, { method: "PUT", body: { password } });
  }

  // ---- manager: serijos ----
  async function addSeries(name) {
    applyState(await api("/api/series", { method: "POST", body: { name } }));
  }
  async function removeSeries(id) {
    applyState(await api(`/api/series/${id}`, { method: "DELETE" }));
    if (selectedSeriesId === id) setSelectedSeriesId(null);
  }
  async function saveIntervalMin(n) {
    applyState(await api("/api/settings/interval", { method: "PUT", body: { intervalMin: n } }));
  }

  const canSeeProducts = role === "manager" || role === "admin";
  const canSeeUsersTab = role === "admin";

  return (
    <div style={{ background: "#F3F4F7", minHeight: "100vh", color: "#111827" }}>
      <div
        style={{
          background: "#0F172A",
          color: "#fff",
          padding: "14px 24px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          flexWrap: "wrap",
          gap: 12,
        }}
      >
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <div
            style={{
              width: 34,
              height: 34,
              borderRadius: 8,
              background: "linear-gradient(135deg,#3B5BFB,#7C3AED)",
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              fontSize: 16,
            }}
          >
            ▦
          </div>
          <div>
            <div style={{ fontWeight: 700, fontSize: 15 }}>Publikavimo grafikas</div>
            <div style={{ fontSize: 11, color: "#94A3B8" }}>serijos · produktai · laiko matrica</div>
          </div>
        </div>

        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 8,
              background: "#1E293B",
              borderRadius: 8,
              padding: "6px 12px",
              fontSize: 13,
            }}
          >
            <span>{ROLE_META[role].emoji}</span>
            <b>{me.name}</b>
            <span style={{ color: "#94A3B8" }}>({ROLE_META[role].label})</span>
          </div>
          <button onClick={onLogout} style={logoutBtn}>
            Atsijungti
          </button>
        </div>
      </div>

      <div style={{ background: "#fff", borderBottom: "1px solid #E5E7EB", padding: "0 24px", display: "flex", gap: 4 }}>
        <TabBtn active={tab === "matrix"} onClick={() => setTab("matrix")}>
          Matrica
        </TabBtn>
        {canSeeProducts && (
          <TabBtn active={tab === "products"} onClick={() => setTab("products")}>
            Serijos ir produktai
          </TabBtn>
        )}
        <TabBtn active={tab === "report"} onClick={() => setTab("report")}>
          Ataskaita
        </TabBtn>
        {canSeeUsersTab && (
          <TabBtn active={tab === "users"} onClick={() => setTab("users")}>
            Vartotojai
          </TabBtn>
        )}
      </div>

      {errorMsg && (
        <div style={{ background: "#FEE2E2", color: "#991B1B", padding: "8px 24px", fontSize: 13 }}>
          {errorMsg}{" "}
          <button onClick={() => setErrorMsg("")} style={{ marginLeft: 8, cursor: "pointer" }}>
            ×
          </button>
        </div>
      )}

      <div style={{ padding: 24, maxWidth: 1400, margin: "0 auto" }}>
        {tab === "matrix" && (
          <MatrixView
            role={role}
            currentUserId={currentUserId}
            matrixUsers={matrixUsers}
            slots={slots}
            date={date}
            setDate={setDate}
            intervalMin={intervalMin}
            saveIntervalMin={saveIntervalMin}
            series={series}
            selectedSeriesId={selectedSeriesId}
            setSelectedSeriesId={setSelectedSeriesId}
            findAssignment={findAssignment}
            computeStatus={computeStatus}
            productsById={productsById}
            onCellClick={onCellClick}
            onIncrement={handleIncrement}
            onDecrement={handleDecrement}
            onDelete={handleDeleteAssignment}
          />
        )}

        {tab === "products" && canSeeProducts && (
          <ProductsView
            series={series}
            products={Object.values(productsById)}
            assignments={assignments}
            users={users}
            addSeries={addSeries}
            removeSeries={removeSeries}
            onDeleteAssignmentForProduct={(productId) => {
              const a = assignments.find((x) => x.productId === productId);
              if (a) handleDeleteAssignment(a.id);
            }}
            selectedSeriesId={selectedSeriesId}
            setSelectedSeriesId={setSelectedSeriesId}
          />
        )}

        {tab === "report" && <ReportView series={series} products={Object.values(productsById)} assignments={assignments} />}

        {tab === "users" && canSeeUsersTab && (
          <UsersView users={users} addUser={addUser} removeUser={removeUser} changeUserRole={changeUserRole} resetPassword={resetPassword} />
        )}
      </div>
    </div>
  );
}

// ==================== MATRICA ====================
function MatrixView(props) {
  const {
    role,
    currentUserId,
    matrixUsers,
    slots,
    date,
    setDate,
    intervalMin,
    saveIntervalMin,
    series,
    selectedSeriesId,
    setSelectedSeriesId,
    findAssignment,
    computeStatus,
    productsById,
    onCellClick,
    onIncrement,
    onDecrement,
    onDelete,
  } = props;

  const [intervalDraft, setIntervalDraft] = useState(intervalMin);
  useEffect(() => setIntervalDraft(intervalMin), [intervalMin]);
  const selectedSeries = series.find((s) => s.id === selectedSeriesId);
  const isManagerView = role === "manager" || role === "admin";

  return (
    <div>
      <div
        style={{
          background: "#fff",
          border: "1px solid #E5E7EB",
          borderRadius: 12,
          padding: 16,
          marginBottom: 16,
          display: "flex",
          flexWrap: "wrap",
          gap: 16,
          alignItems: "flex-end",
        }}
      >
        <Field label="Data">
          <input type="date" value={date} onChange={(e) => setDate(e.target.value)} style={inputStyle} />
        </Field>
        <Field label="Intervalas">
          {isManagerView ? (
            <div style={{ display: "flex", gap: 6 }}>
              <select
                value={intervalDraft}
                onChange={(e) => setIntervalDraft(Number(e.target.value))}
                style={inputStyle}
              >
                {[10, 15, 20, 30, 60].map((v) => (
                  <option key={v} value={v}>
                    {v} min
                  </option>
                ))}
              </select>
              {intervalDraft !== intervalMin && (
                <button onClick={() => saveIntervalMin(intervalDraft)} style={primaryBtn}>
                  Išsaugoti
                </button>
              )}
            </div>
          ) : (
            <div style={{ ...inputStyle, background: "#F9FAFB" }}>{intervalMin} min</div>
          )}
        </Field>

        {isManagerView && (
          <Field label="Serija (priskyrimo režimas)">
            <select
              value={selectedSeriesId || ""}
              onChange={(e) => setSelectedSeriesId(e.target.value)}
              style={{ ...inputStyle, minWidth: 220 }}
            >
              <option value="" disabled>
                Pasirinkite seriją
              </option>
              {series.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.code} — {s.name}
                </option>
              ))}
            </select>
          </Field>
        )}
      </div>

      {isManagerView && selectedSeries && (
        <div style={infoBanner}>
          Priskyrimo režimas: <b>{selectedSeries.code}</b> — spauskite tuščią langelį prie bet kurio
          agento, kad priskirtumėte jam kitą jo asmeninį numerį šioje serijoje. Priskirtame langelyje:{" "}
          <b>−</b> ir <b>+</b> keičia produkto numerį, <b>×</b> viršuje panaikina langelį visiškai.
        </div>
      )}
      {role === "user" && (
        <div style={{ ...infoBanner, background: "#ECFDF5", border: "1px solid #A7F3D0", color: "#065F46" }}>
          Jūsų eilutė paryškinta. Spauskite savo langelį, kad pažymėtumėte paruošta / atlikta.
        </div>
      )}

      <div style={{ display: "flex", gap: 16, marginBottom: 12, flexWrap: "wrap" }}>
        <Legend color="#fff" border="#D1D5DB" dashed label="Nepriskirta" />
        <Legend color="#94A3B8" label="Suplanuota" />
        <Legend color="#EAB308" label="Paruošta" />
        <Legend color="#16A34A" label="Publikuota laiku ✓" />
        <Legend color="#DC2626" label="Vėluoja (nebekeičiama)" />
      </div>

      <div style={{ background: "#fff", border: "1px solid #E5E7EB", borderRadius: 12, overflow: "auto", maxWidth: "100%" }}>
        <table style={{ borderCollapse: "separate", borderSpacing: 0 }}>
          <thead>
            <tr>
              <th style={{ ...thStyle, position: "sticky", left: 0, top: 0, zIndex: 3, background: "#0F172A", color: "#fff", minWidth: 140, textAlign: "left" }}>
                Agentas
              </th>
              {slots.map((t) => (
                <th key={t} style={{ ...thStyle, position: "sticky", top: 0, zIndex: 2, fontFamily: "ui-monospace, monospace", fontSize: 11.5, minWidth: 56 }}>
                  {t}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {matrixUsers.map((u) => {
              const isMe = role === "user" && u.id === currentUserId;
              return (
                <tr key={u.id}>
                  <td style={{ ...tdUserStyle, position: "sticky", left: 0, zIndex: 1, background: isMe ? "#D1FAE5" : "#F8FAFC", fontWeight: isMe ? 700 : 600 }}>
                    {u.name}
                    {isMe && <span style={{ fontSize: 10, color: "#059669", marginLeft: 6 }}>(aš)</span>}
                  </td>
                  {slots.map((t) => {
                    const a = findAssignment(u.id, t);
                    const status = computeStatus(a);
                    const editable =
                      (isManagerView && !!selectedSeriesId && !a) ||
                      (role === "user" && u.id === currentUserId && !!a && !status.locked);
                    return (
                      <Cell
                        key={t}
                        role={isManagerView ? "manager" : role}
                        assignment={a}
                        status={status}
                        product={a ? productsById[a.productId] : null}
                        editable={!!editable}
                        onClick={() => onCellClick(u.id, t)}
                        onIncrement={a ? () => onIncrement(a.productId) : undefined}
                        onDecrement={a ? () => onDecrement(a.productId) : undefined}
                        onDelete={a ? () => onDelete(a.id) : undefined}
                      />
                    );
                  })}
                </tr>
              );
            })}
            {matrixUsers.length === 0 && (
              <tr>
                <td colSpan={slots.length + 1} style={{ padding: 20, textAlign: "center", color: "#9CA3AF" }}>
                  Nėra agentų. Pridėkite jų administratoriaus skiltyje.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function Cell({ role, assignment, status, product, editable, onClick, onIncrement, onDecrement, onDelete }) {
  const { state, published, late, future, ready } = status;
  let style = { ...tdCellStyle, cursor: editable ? "pointer" : "default" };
  let content = null;

  if (state === "empty") {
    style = { ...style, background: "#fff", border: "1px dashed #E2E8F0" };
  } else if (published) {
    style = { ...style, background: "#16A34A", color: "#fff" };
    content = <span style={{ fontSize: 16, fontWeight: 900 }}>✓</span>;
  } else if (late) {
    style = { ...style, background: "#DC2626", color: "#fff", cursor: "default" };
  } else if (future && ready) {
    style = { ...style, background: "#EAB308", color: "#1E293B" };
    content = <span style={{ fontSize: 10, fontWeight: 800 }}>PARUOŠTA</span>;
  } else {
    style = { ...style, background: "#94A3B8", color: "#fff" };
  }

  const isManagerView = role === "manager";
  const controlsActive = isManagerView && state === "assigned";
  const hidden = { visibility: "hidden", pointerEvents: "none" };

  return (
    <td style={{ padding: 3 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 2 }}>
        {isManagerView && (
          <button
            onClick={(e) => {
              e.stopPropagation();
              onDecrement && onDecrement();
            }}
            style={controlsActive ? seqBtnStyle : { ...seqBtnStyle, ...hidden }}
          >
            −
          </button>
        )}
        <div style={{ position: "relative" }}>
          {isManagerView && (
            <button
              onClick={(e) => {
                e.stopPropagation();
                onDelete && onDelete();
              }}
              style={controlsActive ? xBtnStyle : { ...xBtnStyle, ...hidden }}
            >
              ×
            </button>
          )}
          <div onClick={editable ? onClick : undefined} title={product ? product.code : ""} style={{ ...style, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 2 }}>
            {content}
            {product && (
              <span style={{ fontSize: 9, lineHeight: 1.1, maxWidth: 50, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", opacity: 0.9 }}>
                {product.code}
              </span>
            )}
          </div>
        </div>
        {isManagerView && (
          <button
            onClick={(e) => {
              e.stopPropagation();
              onIncrement && onIncrement();
            }}
            style={controlsActive ? seqBtnStyle : { ...seqBtnStyle, ...hidden }}
          >
            +
          </button>
        )}
      </div>
    </td>
  );
}

// ==================== SERIJOS / PRODUKTAI ====================
function ProductsView({ series, products, assignments, users, addSeries, removeSeries, onDeleteAssignmentForProduct, selectedSeriesId, setSelectedSeriesId }) {
  const [newSeriesName, setNewSeriesName] = useState("");
  const matrixUsers = users.filter((u) => u.role === "user");
  const selectedSeries = series.find((s) => s.id === selectedSeriesId);
  const seriesProducts = products.filter((p) => p.seriesId === selectedSeriesId).sort((a, b) => a.seq - b.seq);

  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 1.3fr", gap: 16 }}>
      <Panel title="Produktų serijos">
        <div style={{ display: "flex", gap: 8, marginBottom: 12 }}>
          <input placeholder="Naujos serijos pavadinimas" value={newSeriesName} onChange={(e) => setNewSeriesName(e.target.value)} style={{ ...inputStyle, flex: 1 }} />
          <button
            onClick={() => {
              if (!newSeriesName.trim()) return;
              addSeries(newSeriesName.trim());
              setNewSeriesName("");
            }}
            style={primaryBtn}
          >
            + Pridėti
          </button>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {series.map((s) => (
            <div
              key={s.id}
              onClick={() => setSelectedSeriesId(s.id)}
              style={{ ...rowStyle, background: selectedSeriesId === s.id ? "#EFF3FF" : "#F9FAFB", border: selectedSeriesId === s.id ? "1px solid #93A9FF" : "1px solid #E5E7EB", cursor: "pointer" }}
            >
              <span>
                <span style={{ fontFamily: "ui-monospace, monospace", fontWeight: 700, color: "#2563EB", marginRight: 8 }}>{s.code}</span>
                <span style={{ fontWeight: 600 }}>{s.name}</span>
              </span>
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  removeSeries(s.id);
                }}
                style={iconBtnLight}
              >
                🗑
              </button>
            </div>
          ))}
          {series.length === 0 && <Empty text="Serijų dar nėra." />}
        </div>
      </Panel>

      <Panel title="Produktai pasirinktoje serijoje">
        {!selectedSeries && <Empty text="Pasirinkite seriją kairėje." />}
        {selectedSeries && (
          <>
            <div style={{ fontSize: 12.5, color: "#6B7280", marginBottom: 12, background: "#F9FAFB", border: "1px solid #E5E7EB", borderRadius: 8, padding: "8px 10px" }}>
              Kiekvienas agentas šioje serijoje turi savo, atskirai skaičiuojamą numeraciją — sugeneruojama automatiškai matricoje.
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {matrixUsers.map((u) => {
                const userProducts = seriesProducts.filter((p) => p.userId === u.id);
                if (userProducts.length === 0) return null;
                return (
                  <div key={u.id}>
                    <div style={{ fontSize: 12, fontWeight: 700, color: "#374151", marginBottom: 4 }}>{u.name}</div>
                    <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                      {userProducts.map((p) => (
                        <div key={p.id} style={rowStyle}>
                          <span style={{ fontFamily: "ui-monospace, monospace", fontWeight: 700 }}>{p.code}</span>
                          <button onClick={() => onDeleteAssignmentForProduct(p.id)} style={iconBtnLight}>
                            🗑
                          </button>
                        </div>
                      ))}
                    </div>
                  </div>
                );
              })}
              {seriesProducts.length === 0 && <Empty text="Šioje serijoje produktų dar nėra — priskirkite juos matricoje." />}
            </div>
          </>
        )}
      </Panel>
    </div>
  );
}

// ==================== ATASKAITA ====================
function ReportView({ series, products, assignments }) {
  const assignmentByProductId = Object.fromEntries(assignments.map((a) => [a.productId, a]));
  return (
    <div>
      <div style={{ background: "#F3F4F6", border: "1px solid #E5E7EB", borderRadius: 10, padding: "8px 14px", fontSize: 12.5, color: "#6B7280", marginBottom: 16 }}>
        Tik skaitymui — šios ataskaitos negali redaguoti nei Vadas, nei Agentas.
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        {series.map((s) => {
          const seriesProducts = products.filter((p) => p.seriesId === s.id);
          const bySeq = {};
          for (const p of seriesProducts) {
            if (!bySeq[p.seq]) bySeq[p.seq] = { assigned: 0, publishedOnTime: 0 };
            bySeq[p.seq].assigned += 1;
            const a = assignmentByProductId[p.id];
            if (a && a.published) bySeq[p.seq].publishedOnTime += 1;
          }
          const seqNumbers = Object.keys(bySeq).map(Number).sort((a, b) => a - b);
          return (
            <Panel key={s.id} title={`${s.code} — ${s.name}`}>
              {seqNumbers.length === 0 && <Empty text="Šioje serijoje dar nėra priskirtų produktų." />}
              {seqNumbers.length > 0 && (
                <table style={{ width: "100%", borderCollapse: "collapse" }}>
                  <thead>
                    <tr style={{ textAlign: "left", fontSize: 12, color: "#6B7280" }}>
                      <th style={{ padding: "6px 8px" }}>Numeris</th>
                      <th style={{ padding: "6px 8px" }}>Publikavo laiku</th>
                      <th style={{ padding: "6px 8px" }}>Priskirta agentų</th>
                    </tr>
                  </thead>
                  <tbody>
                    {seqNumbers.map((seq) => {
                      const row = bySeq[seq];
                      return (
                        <tr key={seq} style={{ borderTop: "1px solid #F1F5F9" }}>
                          <td style={{ padding: "8px", fontFamily: "ui-monospace, monospace", fontWeight: 700 }}>
                            {s.code}-{pad(seq, 2)}
                          </td>
                          <td style={{ padding: "8px" }}>
                            <span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: 28, padding: "2px 10px", borderRadius: 999, background: row.publishedOnTime > 0 ? "#DCFCE7" : "#F3F4F6", color: row.publishedOnTime > 0 ? "#166534" : "#6B7280", fontWeight: 700, fontSize: 13 }}>
                              {row.publishedOnTime}
                            </span>
                          </td>
                          <td style={{ padding: "8px", color: "#6B7280", fontSize: 13 }}>{row.assigned}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              )}
            </Panel>
          );
        })}
        {series.length === 0 && <Empty text="Serijų dar nėra." />}
      </div>
    </div>
  );
}

// ==================== VARTOTOJAI (admin) ====================
function UsersView({ users, addUser, removeUser, changeUserRole, resetPassword }) {
  const [name, setName] = useState("");
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [role, setRole] = useState("user");
  const [err, setErr] = useState("");

  async function submit() {
    setErr("");
    if (!name.trim() || !username.trim() || !password) {
      setErr("Užpildykite visus laukus");
      return;
    }
    try {
      await addUser({ name: name.trim(), username: username.trim(), password, role });
      setName("");
      setUsername("");
      setPassword("");
    } catch (e) {
      setErr(e.message);
    }
  }

  return (
    <Panel title="Vartotojų konfigūracija">
      <div style={{ display: "flex", gap: 8, marginBottom: 8, flexWrap: "wrap" }}>
        <input placeholder="Vardas Pavardė" value={name} onChange={(e) => setName(e.target.value)} style={{ ...inputStyle, minWidth: 160 }} />
        <input placeholder="Prisijungimo vardas" value={username} onChange={(e) => setUsername(e.target.value)} style={{ ...inputStyle, minWidth: 140 }} />
        <input placeholder="Slaptažodis" type="text" value={password} onChange={(e) => setPassword(e.target.value)} style={{ ...inputStyle, minWidth: 140 }} />
        <select value={role} onChange={(e) => setRole(e.target.value)} style={inputStyle}>
          <option value="admin">Administratorius</option>
          <option value="manager">Vadas</option>
          <option value="user">Agentas</option>
        </select>
        <button onClick={submit} style={primaryBtn}>
          + Pridėti vartotoją
        </button>
      </div>
      {err && <div style={{ color: "#DC2626", fontSize: 13, marginBottom: 8 }}>{err}</div>}

      <table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead>
          <tr style={{ textAlign: "left", fontSize: 12, color: "#6B7280" }}>
            <th style={{ padding: "6px 8px" }}>Vardas</th>
            <th style={{ padding: "6px 8px" }}>Prisijungimo vardas</th>
            <th style={{ padding: "6px 8px" }}>Rolė</th>
            <th style={{ padding: "6px 8px" }}></th>
          </tr>
        </thead>
        <tbody>
          {users.map((u) => (
            <UserRow key={u.id} u={u} changeUserRole={changeUserRole} removeUser={removeUser} resetPassword={resetPassword} />
          ))}
        </tbody>
      </table>
    </Panel>
  );
}

function UserRow({ u, changeUserRole, removeUser, resetPassword }) {
  const [newPass, setNewPass] = useState("");
  return (
    <tr style={{ borderTop: "1px solid #F1F5F9" }}>
      <td style={{ padding: "8px", fontWeight: 600 }}>{u.name}</td>
      <td style={{ padding: "8px", color: "#6B7280" }}>{u.username}</td>
      <td style={{ padding: "8px" }}>
        <select value={u.role} onChange={(e) => changeUserRole(u.id, e.target.value)} style={{ ...inputStyle, padding: "4px 8px", fontSize: 12.5 }}>
          <option value="admin">Administratorius</option>
          <option value="manager">Vadas</option>
          <option value="user">Agentas</option>
        </select>
      </td>
      <td style={{ padding: "8px", textAlign: "right", display: "flex", gap: 6, justifyContent: "flex-end" }}>
        <input
          placeholder="naujas slaptažodis"
          value={newPass}
          onChange={(e) => setNewPass(e.target.value)}
          style={{ ...inputStyle, padding: "4px 8px", fontSize: 12, width: 130 }}
        />
        <button
          onClick={() => {
            if (newPass) {
              resetPassword(u.id, newPass);
              setNewPass("");
            }
          }}
          style={iconBtnLight}
          title="Nustatyti naują slaptažodį"
        >
          🔑
        </button>
        <button onClick={() => removeUser(u.id)} style={iconBtnLight} title="Pašalinti">
          🗑
        </button>
      </td>
    </tr>
  );
}

// ==================== bendri UI elementai ====================
function TabBtn({ active, onClick, children }) {
  return (
    <button
      onClick={onClick}
      style={{
        padding: "12px 14px",
        border: "none",
        background: "none",
        cursor: "pointer",
        fontSize: 13.5,
        fontWeight: 600,
        color: active ? "#111827" : "#9CA3AF",
        borderBottom: active ? "2px solid #2563EB" : "2px solid transparent",
      }}
    >
      {children}
    </button>
  );
}
function Field({ label, children }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
      <span style={{ fontSize: 11, color: "#6B7280", fontWeight: 600 }}>{label}</span>
      {children}
    </div>
  );
}
function Legend({ color, border, dashed, label }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "#4B5563" }}>
      <span style={{ width: 14, height: 14, borderRadius: 4, background: color, border: border ? `1px ${dashed ? "dashed" : "solid"} ${border}` : "none" }} />
      {label}
    </div>
  );
}
function Panel({ title, children }) {
  return (
    <div style={{ background: "#fff", border: "1px solid #E5E7EB", borderRadius: 12, padding: 18 }}>
      <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 14 }}>{title}</div>
      {children}
    </div>
  );
}
function Empty({ text }) {
  return <div style={{ color: "#9CA3AF", fontSize: 13, padding: "10px 0" }}>{text}</div>;
}

// ---------------- stiliai ----------------
const fieldLabel = { display: "block", fontSize: 12, fontWeight: 600, color: "#374151", marginBottom: 4 };
const inputStyle = { border: "1px solid #D1D5DB", borderRadius: 8, padding: "7px 10px", fontSize: 13, outline: "none", background: "#fff", width: "100%" };
const primaryBtn = { display: "inline-flex", alignItems: "center", gap: 6, background: "#2563EB", color: "#fff", border: "none", borderRadius: 8, padding: "7px 14px", fontSize: 13, fontWeight: 600, cursor: "pointer" };
const logoutBtn = { background: "#374151", color: "#fff", border: "none", borderRadius: 8, padding: "7px 14px", fontSize: 13, fontWeight: 600, cursor: "pointer" };
const iconBtnLight = { background: "none", border: "none", cursor: "pointer", padding: 4, borderRadius: 6 };
const rowStyle = { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "9px 12px", borderRadius: 8 };
const thStyle = { background: "#0F172A", color: "#E2E8F0", padding: "8px 6px", fontSize: 12, fontWeight: 700, textAlign: "center", borderRight: "1px solid #1E293B" };
const tdUserStyle = { padding: "8px 12px", fontSize: 13, borderBottom: "1px solid #F1F5F9", borderRight: "1px solid #F1F5F9", whiteSpace: "nowrap" };
const tdCellStyle = { width: 50, height: 42, borderRadius: 6, color: "#1E293B" };
const seqBtnStyle = { width: 16, height: 42, flexShrink: 0, border: "1px solid #E5E7EB", background: "#F3F4F6", color: "#374151", borderRadius: 4, fontSize: 13, fontWeight: 800, cursor: "pointer", padding: 0, lineHeight: "1" };
const xBtnStyle = { position: "absolute", top: -7, left: "50%", transform: "translateX(-50%)", width: 15, height: 15, borderRadius: "50%", border: "1px solid #fff", background: "#374151", color: "#fff", fontSize: 10, lineHeight: "13px", padding: 0, cursor: "pointer", zIndex: 2 };
const infoBanner = { background: "#EFF3FF", border: "1px solid #C7D5FE", color: "#2545C9", borderRadius: 10, padding: "8px 14px", fontSize: 13, marginBottom: 14 };

ReactDOM.createRoot(document.getElementById("root")).render(<Root />);
