/* global React */

function Dashboard({ onTab, onStartGenerate, onReload }) {
  const { STATS, LOGS, UNSCHEDULED, CONFLICTS, isPending } = window.SCHED_DATA;

  const [uploading, setUploading] = useState({});
  const [generating, setGenerating] = useState(false);
  const [committing, setCommitting] = useState(false);
  const [genResult, setGenResult] = useState(null);
  const [errorMsg, setErrorMsg] = useState("");
  const pollingRef = useRef(null);

  useEffect(() => {
    window.API.get("/api/schedule/generate/status").then(s => {
      if (s.in_progress) {
        setGenerating(true);
        startPolling();
      }
    }).catch(() => {});
    return () => clearInterval(pollingRef.current);
  }, []);

  function startPolling() {
    clearInterval(pollingRef.current);
    pollingRef.current = setInterval(async () => {
      try {
        const s = await window.API.get("/api/schedule/generate/status");
        if (!s.in_progress) {
          clearInterval(pollingRef.current);
          setGenerating(false);
          await onReload();
        }
      } catch {}
    }, 2000);
  }

  // Derive pipeline status from real stats
  const roomsDone = STATS.rooms > 0;
  const form1Done = STATS.lessons > 0;
  // departments: no direct signal — infer from localStorage flag or schedule
  const deptDone = localStorage.getItem("sched_dept_uploaded") === "1" || STATS.scheduled > 0;
  const generatedDone = STATS.scheduled > 0;

  async function handleUpload(endpoint, file, stateKey) {
    setUploading(u => ({ ...u, [stateKey]: true }));
    setErrorMsg("");
    try {
      await window.API.upload(`/api/import/${endpoint}`, file);
      if (stateKey === "departments") localStorage.setItem("sched_dept_uploaded", "1");
      await onReload();
    } catch (e) {
      setErrorMsg(`Ошибка загрузки: ${e.message}`);
    } finally {
      setUploading(u => ({ ...u, [stateKey]: false }));
    }
  }

  async function handleCommit() {
    setCommitting(true);
    setErrorMsg("");
    try {
      await window.API.post("/api/schedule/commit", {});
      await onReload();
    } catch (e) {
      setErrorMsg(`Ошибка сохранения: ${e.message}`);
    } finally {
      setCommitting(false);
    }
  }

  async function handleGenerate() {
    setGenerating(true);
    setErrorMsg("");
    setGenResult(null);
    startPolling();
    try {
      const result = await window.API.post("/api/schedule/generate", {});
      clearInterval(pollingRef.current);
      setGenResult(result);
      await onReload();
    } catch (e) {
      clearInterval(pollingRef.current);
      setErrorMsg(`Ошибка генерации: ${e.message}`);
    } finally {
      setGenerating(false);
    }
  }

  const subTitle = generatedDone
    ? `Расписание сгенерировано: ${STATS.scheduled} слотов, ${STATS.unscheduled} незапланировано, ${STATS.conflicts} конфликтов.`
    : form1Done
      ? "Данные загружены. Выставьте настройки и нажмите «Сгенерировать»."
      : "Загрузите данные (аудитории, Форму 1, кафедры) для начала работы.";

  return (
    <div style={{ padding: "32px 40px", maxWidth: 1440, margin: "0 auto", width: "100%", overflow: "auto" }}>
      <div className="sectionHeader">
        <div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--ink-3)", letterSpacing: "0.08em", textTransform: "uppercase", marginBottom: 10 }}>— ОБЗОР · весенний семестр 2025/26</div>
          <div className="sectionHeader__title">
            {generatedDone ? <>Все данные <em>на месте.</em></> : <>Добро <em>пожаловать.</em></>}
          </div>
          <div className="sectionHeader__sub">{subTitle}</div>
        </div>
        <div className="sectionHeader__actions">
          <a
            href={`${window.API_BASE}/api/export/groups?token=${window.API_TOKEN}`}
            className="btn btn--ghost"
            style={{ display: "inline-flex", alignItems: "center", gap: 6 }}
            target="_blank"
          >
            <Icon name="download" /> Экспорт (группы)
          </a>
          <button
            className="btn btn--primary"
            onClick={handleGenerate}
            disabled={generating || !form1Done}
          >
            <Icon name="sparkle" /> {generating ? "Генерация…" : "Сгенерировать"}
          </button>
        </div>
      </div>

      {isPending && (
        <div style={{
          display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16,
          padding: "14px 20px", marginBottom: 20,
          background: "var(--accent-soft)", border: "1px solid var(--accent)",
          borderRadius: 8,
        }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <Icon name="sparkle" size={16} />
            <div>
              <div style={{ fontSize: 13, fontWeight: 600, color: "var(--accent)" }}>Черновик расписания</div>
              <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 2 }}>
                Расписание сгенерировано, но ещё не сохранено. Просмотрите и нажмите «Сохранить».
              </div>
            </div>
          </div>
          <button className="btn btn--primary" onClick={handleCommit} disabled={committing} style={{ flexShrink: 0 }}>
            {committing ? "Сохранение…" : "Сохранить расписание"}
          </button>
        </div>
      )}

      {errorMsg && (
        <div style={{ padding: "12px 16px", background: "var(--danger-soft)", border: "1px solid var(--danger)", borderRadius: 6, fontSize: 13, color: "var(--danger)", marginBottom: 20 }}>
          {errorMsg}
        </div>
      )}

      {genResult && (
        <div style={{ padding: "12px 16px", background: "var(--success-soft)", border: "1px solid var(--success)", borderRadius: 6, fontSize: 13, color: "var(--success)", marginBottom: 20 }}>
          Готово: {genResult.scheduled_slots} размещено, {genResult.unscheduled_items} нет слотов.
        </div>
      )}

      {/* Stats strip */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 0, border: "1px solid var(--line)", borderRadius: "var(--radius-lg)", background: "var(--surface)", marginBottom: 28, overflow: "hidden" }}>
        {[
          { label: "ЗАНЯТИЯ", value: STATS.lessons, sub: "всего в Форме 1" },
          { label: "РАЗМЕЩЕНО", value: STATS.scheduled, sub: STATS.lessons > 0 ? `${Math.round(STATS.scheduled / STATS.lessons * 100)}% покрытие` : "—", tone: "success" },
          { label: "НЕРАЗМЕЩЕНО", value: STATS.unscheduled, sub: "требуют внимания", tone: "warn" },
          { label: "КОНФЛИКТОВ", value: STATS.conflicts, sub: "в черновике", tone: "danger" },
          { label: "АУДИТОРИИ", value: STATS.rooms, sub: "загружено" },
        ].map((s, i) => (
          <div key={s.label} style={{ padding: "22px 24px", borderRight: i < 4 ? "1px solid var(--line-soft)" : "none" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--ink-3)", letterSpacing: "0.1em", marginBottom: 10 }}>{s.label}</div>
            <div style={{
              fontFamily: "var(--font-serif)",
              fontSize: 52,
              lineHeight: 0.9,
              color: s.tone === "warn" ? "var(--warn)" : s.tone === "danger" ? "var(--danger)" : s.tone === "success" ? "var(--success)" : "var(--ink)",
              fontVariantNumeric: "tabular-nums",
            }}>{s.value}</div>
            <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 6 }}>{s.sub}</div>
          </div>
        ))}
      </div>

      {/* Pipeline | Activity */}
      <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 20, marginBottom: 20 }}>
        <div className="card">
          <div className="card__header">
            <div className="card__title"><span className="num">i.</span> Конвейер данных</div>
            <div style={{ fontSize: 12, color: "var(--ink-3)" }}>4 шага · автоматически</div>
          </div>
          <div style={{ padding: "4px 22px 22px" }}>
            <PipelineStep
              num="01"
              name="Аудитории"
              hint="Номера, вместимость, тип, корпус"
              status={{ done: roomsDone, count: STATS.rooms, file: roomsDone ? `${STATS.rooms} аудиторий` : "" }}
              uploading={!!uploading.rooms}
              onUpload={file => handleUpload("rooms", file, "rooms")}
            />
            <PipelineStep
              num="02"
              name="Форма 1"
              hint="Группы, дисциплины, преподаватели, часы"
              status={{ done: form1Done, count: STATS.lessons, file: form1Done ? `${STATS.lessons} занятий` : "" }}
              uploading={!!uploading.form1}
              onUpload={file => handleUpload("form1", file, "form1")}
            />
            <PipelineStep
              num="03"
              name="Кафедры"
              hint="Привязка преподавателей к корпусам"
              status={{ done: deptDone, count: 0, file: deptDone ? "загружено" : "" }}
              uploading={!!uploading.departments}
              onUpload={file => handleUpload("departments", file, "departments")}
            />
            <PipelineStep
              num="04"
              name="Генерация"
              hint="Расстановка по слотам с учётом настроек"
              status={{ done: generatedDone, count: STATS.scheduled, file: generatedDone ? `${STATS.scheduled} слотов` : "" }}
              last
            />
          </div>
        </div>

        <div className="card">
          <div className="card__header">
            <div className="card__title"><span className="num">ii.</span> Активность</div>
            <div style={{ fontSize: 12, color: "var(--ink-3)" }}>сегодня</div>
          </div>
          <div style={{ padding: "6px 22px 20px" }}>
            {LOGS.length === 0 ? (
              <div style={{ padding: "24px 0", textAlign: "center", fontSize: 13, color: "var(--ink-4)", fontStyle: "italic" }}>
                Нет записей
              </div>
            ) : LOGS.map((l, i) => (
              <div key={i} style={{
                display: "flex",
                alignItems: "flex-start",
                gap: 12,
                padding: "10px 0",
                borderBottom: i < LOGS.length - 1 ? "1px solid var(--line-soft)" : "none",
              }}>
                <div style={{
                  width: 8, height: 8, borderRadius: "50%",
                  marginTop: 6,
                  flexShrink: 0,
                  background: l.tone === "success" ? "var(--success)" : l.tone === "error" ? "var(--danger)" : "var(--info)",
                }}/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, lineHeight: 1.5 }}>{l.text}</div>
                </div>
                <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--ink-4)", flexShrink: 0 }}>{l.t}</div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Export + Attention */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, marginBottom: 40 }}>
        <div className="card">
          <div className="card__header">
            <div className="card__title"><span className="num">iii.</span> Экспорт в Excel</div>
            <div style={{ fontSize: 12, color: "var(--ink-3)" }}>xlsx · шаблон ректората</div>
          </div>
          <div style={{ padding: "16px 22px 22px", display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10 }}>
            {[
              { label: "По группам", sub: `${STATS.groups} групп`, icon: "users", href: `${window.API_BASE}/api/export/groups?token=${window.API_TOKEN}` },
              { label: "По преподавателям", sub: `${STATS.teachers} препод.`, icon: "book", href: `${window.API_BASE}/api/export/teachers?token=${window.API_TOKEN}` },
              { label: "По шаблону", sub: "сводная", icon: "grid", href: `${window.API_BASE}/api/export/template?token=${window.API_TOKEN}` },
            ].map(x => (
              <a key={x.label} href={x.href} target="_blank"
                className="btn btn--ghost"
                style={{
                  flexDirection: "column",
                  alignItems: "flex-start",
                  padding: "14px 16px",
                  height: "auto",
                  gap: 10,
                  textAlign: "left",
                  width: "100%",
                  display: "flex",
                  opacity: generatedDone ? 1 : 0.4,
                  pointerEvents: generatedDone ? "auto" : "none",
                }}>
                <Icon name={x.icon} size={18} />
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{x.label}</div>
                  <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{x.sub}</div>
                </div>
              </a>
            ))}
          </div>
        </div>

        <div className="card" style={{ background: "linear-gradient(170deg, var(--paper) 0%, var(--surface) 100%)" }}>
          <div className="card__header">
            <div className="card__title"><span className="num">iv.</span> Требует внимания</div>
            <button className="btn btn--subtle btn--sm" onClick={() => onTab("schedule")}>
              Перейти <Icon name="arrow-right" size={12} />
            </button>
          </div>
          <div style={{ padding: "14px 22px 18px" }}>
            {STATS.unscheduled > 0 ? (
              <div style={{
                display: "flex", gap: 14, padding: "12px 14px", borderRadius: 6,
                background: "var(--warn-soft)", marginBottom: 8,
              }}>
                <Icon name="alert" size={18} />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: "var(--warn)" }}>{STATS.unscheduled} занятий не размещено</div>
                  {UNSCHEDULED.slice(0, 2).map(u => (
                    <div key={u.dbId} style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 2 }}>
                      «{u.discipline}» ({u.groups.join(", ")})
                    </div>
                  ))}
                </div>
              </div>
            ) : (
              <div style={{
                display: "flex", gap: 14, padding: "12px 14px", borderRadius: 6,
                background: "var(--success-soft)", marginBottom: 8,
              }}>
                <Icon name="check" size={18} />
                <div style={{ fontSize: 13, color: "var(--success)" }}>Все занятия размещены</div>
              </div>
            )}
            {STATS.conflicts > 0 ? (
              <div style={{
                display: "flex", gap: 14, padding: "12px 14px", borderRadius: 6,
                background: "var(--danger-soft)",
              }}>
                <Icon name="alert" size={18} />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, color: "var(--danger)" }}>{STATS.conflicts} конфликтов</div>
                  {CONFLICTS.slice(0, 2).map((c, i) => (
                    <div key={i} style={{ fontSize: 12, color: "var(--ink-2)", marginTop: 2 }}>{c.description}</div>
                  ))}
                </div>
              </div>
            ) : STATS.scheduled > 0 ? (
              <div style={{
                display: "flex", gap: 14, padding: "12px 14px", borderRadius: 6,
                background: "var(--success-soft)",
              }}>
                <Icon name="check" size={18} />
                <div style={{ fontSize: 13, color: "var(--success)" }}>Конфликтов нет</div>
              </div>
            ) : (
              <div style={{ padding: "12px 14px", fontSize: 13, color: "var(--ink-3)" }}>
                Сгенерируйте расписание, чтобы увидеть статус.
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function PipelineStep({ num, name, hint, status, last, onUpload, uploading }) {
  const inputRef = useRef(null);
  return (
    <div style={{
      display: "grid",
      gridTemplateColumns: "36px 1fr auto auto",
      alignItems: "center",
      gap: 18,
      padding: "18px 0",
      borderBottom: last ? "none" : "1px solid var(--line-soft)",
    }}>
      <div style={{
        fontFamily: "var(--font-serif)",
        fontSize: 26,
        fontStyle: "italic",
        color: status.done ? "var(--accent)" : "var(--ink-4)",
      }}>{num}</div>
      <div>
        <div style={{ fontSize: 14, fontWeight: 600 }}>{name}</div>
        <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 2 }}>{hint}</div>
      </div>
      <div style={{ textAlign: "right" }}>
        <div style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--ink)" }}>
          {status.file || "—"}
        </div>
        <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>
          {status.done && status.count > 0 ? `${status.count} записей` : status.done ? "загружено" : "не загружено"}
        </div>
      </div>
      <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
        {status.done && (
          <span className="badge badge--success"><Icon name="check" size={11} /> готово</span>
        )}
        {onUpload && (
          <>
            <input
              ref={inputRef}
              type="file"
              accept=".xlsx,.xls"
              style={{ display: "none" }}
              onChange={e => {
                if (e.target.files[0]) { onUpload(e.target.files[0]); e.target.value = ""; }
              }}
            />
            <button
              className={`btn btn--sm ${status.done ? "btn--subtle" : "btn--ghost"}`}
              onClick={() => inputRef.current.click()}
              disabled={uploading}
            >
              <Icon name="upload" size={12} />
              {uploading ? "загрузка…" : status.done ? "обновить" : "загрузить"}
            </button>
          </>
        )}
      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
