// Documents page — backed by the Go API (real upload / list / download / delete).
// Files are stored as-is; text/OCR extraction (incl. scans) is the AI layer's job.

function Documents() {
  const [docs, setDocs] = React.useState([]);
  const [selected, setSelected] = React.useState(new Set());
  const [dragOver, setDragOver] = React.useState(false);
  const [filterType, setFilterType] = React.useState("all");
  const [filterDate, setFilterDate] = React.useState("any");
  const [query, setQuery] = React.useState("");
  const [uploading, setUploading] = React.useState(0);
  const [error, setError] = React.useState("");
  const [aiDoc, setAiDoc] = React.useState(null);
  const [analyzeNow, setAnalyzeNow] = React.useState(false);
  const fileInputRef = React.useRef(null);

  // Merge an analysis result (summary/analyzedAt) back into the list row.
  const applyAnalysis = (id, patch) =>
    setDocs(prev => prev.map(d => (d.id === id ? { ...d, ...patch } : d)));

  React.useEffect(() => {
    if (window.API && window.API.listDocuments) {
      window.API.listDocuments().then(setDocs).catch(() => setDocs(DOCS));
    } else {
      setDocs(DOCS);
    }
  }, []);

  const inRange = (dstr, mode) => {
    if (mode === "any") return true;
    const m = (dstr || "").match(/(\d{2})\.(\d{2})\.(\d{4})/);
    if (!m) return true;
    const d = new Date(+m[3], +m[2] - 1, +m[1]);
    const days = (Date.now() - d.getTime()) / 86400000;
    if (mode === "today") return days < 1;
    if (mode === "week") return days < 7;
    return true;
  };

  const filtered = docs.filter(d => {
    if (filterType !== "all" && d.type !== filterType) return false;
    if (query && !d.name.toLowerCase().includes(query.toLowerCase())) return false;
    if (!inRange(d.date, filterDate)) return false;
    return true;
  });

  const allSelected = filtered.length > 0 && filtered.every(d => selected.has(d.id));
  const toggleAll = () => {
    if (allSelected) setSelected(new Set());
    else setSelected(new Set(filtered.map(d => d.id)));
  };
  const toggleOne = (id) => {
    const s = new Set(selected);
    s.has(id) ? s.delete(id) : s.add(id);
    setSelected(s);
  };

  const uploadFiles = async (fileList) => {
    const files = Array.from(fileList || []);
    if (!files.length || !window.API) return;
    setError("");
    setUploading(files.length);
    try {
      const created = await window.API.uploadDocuments(files);
      setDocs(prev => [...created, ...prev]);
      // Optionally kick off AI analysis right away (otherwise it's lazy on first open).
      if (analyzeNow && window.API.analyzeDocument) {
        created.forEach(d => {
          window.API.analyzeDocument(d.id)
            .then(r => applyAnalysis(d.id, { summary: r.summary, analyzedAt: r.analyzedAt }))
            .catch(() => {});
        });
      }
    } catch (e) {
      setError("Не удалось загрузить: " + String((e && e.message) || e));
    } finally {
      setUploading(0);
    }
  };

  const removeSelected = async () => {
    const ids = [...selected];
    setDocs(prev => prev.filter(d => !selected.has(d.id)));
    setSelected(new Set());
    if (window.API) {
      for (const id of ids) {
        try { await window.API.deleteDocument(id); } catch (_) {}
      }
    }
  };

  const handleDrop = (e) => {
    e.preventDefault();
    setDragOver(false);
    uploadFiles(e.dataTransfer.files);
  };
  const handleFileInput = (e) => {
    uploadFiles(e.target.files);
    e.target.value = "";
  };
  const demoFile = () => {
    const f = new File(
      ["Демо-файл CRM\nЗагружен для проверки конвейера документов.\n"],
      "Демо_файл.txt", { type: "text/plain" }
    );
    uploadFiles([f]);
  };
  const downloadUrl = (d) => (window.API && window.API.docDownloadUrl ? window.API.docDownloadUrl(d.id) : "#");

  return (
    <div className="page page-fade">
      <div className="page-head">
        <div>
          <h1 className="page-title">Документы</h1>
          <p className="page-subtitle">{docs.length} файлов в библиотеке{uploading ? ` · загрузка ${uploading}…` : ""}</p>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button className="btn btn-primary" onClick={() => fileInputRef.current?.click()}>
            <I.Upload size={14} /> Загрузить
          </button>
          <input ref={fileInputRef} type="file" multiple style={{ display: "none" }} onChange={handleFileInput} />
        </div>
      </div>

      <div
        className={`dropzone ${dragOver ? "over" : ""}`}
        style={{ marginBottom: 18 }}
        onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onDrop={handleDrop}
        onClick={() => fileInputRef.current?.click()}
      >
        <div className="icon-wrap"><I.Upload size={24} /></div>
        <h3>{dragOver ? "Отпустите для загрузки" : "Перетащите файлы сюда"}</h3>
        <p>или нажмите для выбора · Excel, PDF, DOCX, CSV, фото/сканы · ИИ извлечёт текст и резюме</p>
        <div style={{ display: "flex", gap: 8, justifyContent: "center" }}>
          <button className="btn btn-outline" onClick={(e) => { e.stopPropagation(); fileInputRef.current?.click(); }}>
            <I.File size={13} /> Выбрать файлы
          </button>
          <button className="btn btn-ghost" onClick={(e) => { e.stopPropagation(); demoFile(); }}>
            <I.Sparkle size={13} /> Демо-файл
          </button>
        </div>
        <label
          onClick={(e) => e.stopPropagation()}
          style={{ display: "inline-flex", alignItems: "center", gap: 7, marginTop: 12, fontSize: 12.5, color: "var(--ink-500)", cursor: "pointer" }}
        >
          <input type="checkbox" checked={analyzeNow} onChange={(e) => setAnalyzeNow(e.target.checked)} />
          <I.Sparkle size={12} /> Обрабатывать ИИ сразу после загрузки
        </label>
        {error && <p style={{ color: "var(--err)", margin: "10px 0 0" }}>{error}</p>}
      </div>

      <Card bodyStyle={{ padding: 0 }}>
        <div style={{ padding: "14px 16px", borderBottom: "1px solid var(--ink-100)", display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
          <div className="search" style={{ maxWidth: 280, flex: "1 1 220px", minWidth: 200 }}>
            <I.Search size={14} />
            <input placeholder="Поиск по названию…" value={query} onChange={e => setQuery(e.target.value)} />
          </div>

          <div className="field">
            <I.Filter size={12} />
            <select value={filterType} onChange={e => setFilterType(e.target.value)}>
              <option value="all">Все типы</option>
              <option value="xlsx">Excel</option>
              <option value="pdf">PDF</option>
              <option value="docx">DOCX</option>
              <option value="csv">CSV</option>
            </select>
          </div>

          <div className="field">
            <I.Calendar size={12} />
            <select value={filterDate} onChange={e => setFilterDate(e.target.value)}>
              <option value="any">За всё время</option>
              <option value="today">Сегодня</option>
              <option value="week">Эта неделя</option>
            </select>
          </div>

          <div style={{ marginLeft: "auto", display: "flex", gap: 8, alignItems: "center" }}>
            {selected.size > 0 && (
              <>
                <span style={{ fontSize: 12.5, color: "var(--ink-400)" }}>Выбрано: {selected.size}</span>
                <button className="btn btn-danger" onClick={removeSelected}>
                  <I.Trash size={13} /> Удалить
                </button>
              </>
            )}
          </div>
        </div>

        <div className="tbl-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th style={{ width: 40 }}><CheckBox on={allSelected} onChange={toggleAll} /></th>
                <th style={{ width: "44%" }}>Имя файла</th>
                <th>Тип</th>
                <th>Загружен</th>
                <th>Размер</th>
                <th>Статус</th>
                <th style={{ width: 40 }}></th>
              </tr>
            </thead>
            <tbody>
              {filtered.length === 0 && (
                <tr><td colSpan="7" style={{ textAlign: "center", padding: "40px 16px", color: "var(--ink-400)" }}>
                  {docs.length === 0 ? "Пока нет загруженных документов — перетащите файл выше" : "По текущим фильтрам ничего не найдено"}
                </td></tr>
              )}
              {filtered.map(d => (
                <tr key={d.id}>
                  <td><CheckBox on={selected.has(d.id)} onChange={() => toggleOne(d.id)} /></td>
                  <td>
                    <div className="file-cell">
                      <FileIcon type={d.type} />
                      <span style={{ fontWeight: 500 }}>{d.name}</span>
                      {d.analyzedAt && (
                        <span className="pill" style={{ background: "var(--accent-soft)", color: "var(--accent-strong)", fontSize: 10, gap: 3 }} title={"Проанализировано ИИ · " + d.analyzedAt}>
                          <I.Sparkle size={10} /> ИИ
                        </span>
                      )}
                    </div>
                  </td>
                  <td><span className="pill muted" style={{ textTransform: "uppercase", fontSize: 10.5, letterSpacing: ".05em" }}>{d.type || "file"}</span></td>
                  <td style={{ color: "var(--ink-500)", fontFeatureSettings: '"tnum"' }}>{d.date}</td>
                  <td style={{ color: "var(--ink-500)", fontFeatureSettings: '"tnum"' }}>{d.size}</td>
                  <td><Pill kind={STATUS_LABELS[d.status] ? STATUS_LABELS[d.status].cls : "muted"}>{STATUS_LABELS[d.status] ? STATUS_LABELS[d.status].label : d.status}</Pill></td>
                  <td>
                    <div style={{ display: "flex", gap: 2 }}>
                      <button className="icon-btn" style={{ color: d.analyzedAt ? "var(--accent-strong)" : "var(--ink-400)" }} onClick={() => setAiDoc(d)} title="Анализ ИИ">
                        <I.Sparkle size={16} />
                      </button>
                      <a className="icon-btn" style={{ color: "var(--ink-400)" }} href={downloadUrl(d)} title="Скачать" download>
                        <I.Download size={16} />
                      </a>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>

      {aiDoc && (
        <DocAIModal
          doc={aiDoc}
          onClose={() => setAiDoc(null)}
          onAnalyzed={(patch) => applyAnalysis(aiDoc.id, patch)}
        />
      )}
    </div>
  );
}

// DocAIModal shows the AI extraction (OCR) of a document: a short summary and the
// full extracted text. Extraction is lazy + cached on the backend — the first
// open of an un-analyzed document triggers it; afterwards it loads from cache.
function DocAIModal({ doc, onClose, onAnalyzed }) {
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState("");
  const [summary, setSummary] = React.useState(doc.summary || "");
  const [text, setText] = React.useState("");
  const [analyzedAt, setAnalyzedAt] = React.useState(doc.analyzedAt || "");

  const load = React.useCallback(async (force) => {
    if (!window.API) return;
    setLoading(true);
    setError("");
    try {
      if (force) await window.API.analyzeDocument(doc.id, true);
      const r = await window.API.documentText(doc.id);
      setSummary(r.summary || "");
      setText(r.text || "");
      setAnalyzedAt(r.analyzedAt || "");
      onAnalyzed && onAnalyzed({ summary: r.summary || "", analyzedAt: r.analyzedAt || "" });
    } catch (e) {
      setError(String((e && e.message) || e));
    } finally {
      setLoading(false);
    }
  }, [doc.id, onAnalyzed]);

  // Auto-load cached text for already-analyzed documents; otherwise wait for click.
  React.useEffect(() => {
    if (doc.analyzedAt) load(false);
  }, [doc.id]);

  const analyzed = !!analyzedAt;

  return (
    <div className="tg-overlay open" style={{ background: "rgba(13,22,32,.5)", display: "grid", placeItems: "center", zIndex: 260 }} onClick={onClose}>
      <div className="card" style={{ width: 720, maxWidth: "94vw", boxShadow: "var(--sh-3)" }} onClick={e => e.stopPropagation()}>
        <div className="card-head">
          <div style={{ flex: 1, minWidth: 0 }}>
            <h3 className="card-title" style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <I.Sparkle size={16} /> Анализ документа
            </h3>
            <p className="card-sub" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{doc.name}</p>
          </div>
          <button className="icon-btn" style={{ color: "var(--ink-400)" }} onClick={onClose}><I.X size={18} /></button>
        </div>

        <div className="card-body" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          {!analyzed && !loading && !error && (
            <div style={{ textAlign: "center", padding: "26px 12px", color: "var(--ink-400)" }}>
              <div className="icon-wrap" style={{ margin: "0 auto 12px" }}><I.Sparkle size={22} /></div>
              <p style={{ margin: "0 0 4px", color: "var(--ink-500)" }}>Документ ещё не проанализирован</p>
              <p style={{ margin: 0, fontSize: 12.5 }}>ИИ извлечёт текст (включая распознавание сканов) и составит краткое резюме. Результат сохранится.</p>
            </div>
          )}

          {loading && (
            <div style={{ textAlign: "center", padding: "26px 12px", color: "var(--ink-400)" }}>
              <div className="icon-wrap" style={{ margin: "0 auto 12px" }}><I.Refresh size={20} /></div>
              <p style={{ margin: 0 }}>ИИ обрабатывает документ…</p>
            </div>
          )}

          {error && (
            <div style={{ background: "var(--err-soft, #fdecec)", color: "var(--err)", borderRadius: "var(--r-md)", padding: "12px 14px", fontSize: 12.5 }}>
              {error}
            </div>
          )}

          {!loading && summary && (
            <div>
              <label className="fld-label">Краткое резюме</label>
              <div style={{ background: "var(--accent-soft)", color: "var(--ink-700)", borderRadius: "var(--r-md)", padding: "12px 14px", fontSize: 13, lineHeight: 1.5 }}>
                {summary}
              </div>
            </div>
          )}

          {!loading && text && (
            <div>
              <label className="fld-label">Извлечённый текст</label>
              <div style={{ background: "var(--ink-50)", border: "1px solid var(--ink-100)", borderRadius: "var(--r-md)", padding: "12px 14px", fontSize: 12.5, lineHeight: 1.5, whiteSpace: "pre-wrap", maxHeight: 340, overflow: "auto", fontFamily: "var(--sans)" }}>
                {text}
              </div>
            </div>
          )}
        </div>

        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8, padding: "0 20px 18px" }}>
          <span style={{ fontSize: 11.5, color: "var(--ink-400)" }}>{analyzed ? "Проанализировано · " + analyzedAt : ""}</span>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-ghost" onClick={onClose}>Закрыть</button>
            {analyzed ? (
              <button className="btn btn-outline" onClick={() => load(true)} disabled={loading} style={loading ? { opacity: 0.4, pointerEvents: "none" } : null}>
                <I.Refresh size={14} /> Переанализировать
              </button>
            ) : (
              <button className="btn btn-accent" onClick={() => load(false)} disabled={loading} style={loading ? { opacity: 0.4, pointerEvents: "none" } : null}>
                <I.Sparkle size={14} /> {loading ? "Анализ…" : "Анализировать"}
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

window.Documents = Documents;
