import { useEffect, useLayoutEffect, useRef, useState } from "react";
import "./App.css";
import { Client } from "./ot/client";
import { generateOperations } from "./ot/helpers";
import { getDemoServerInstance } from "./ot/server";

function Editor({ name }: { name: string }) {
  const clientRef = useRef<Client | null>(null);
  const [doc, setDoc] = useState<string>("");
  const prevDocRef = useRef<string>("");
  const [enableSync, setEnableSync] = useState<boolean>(true);

  // 初始化client和文档状态
  useLayoutEffect(() => {
    if (!clientRef.current) {
      clientRef.current = new Client();
      clientRef.current.name = name;
      const initialDoc = clientRef.current.document || "";
      prevDocRef.current = initialDoc;
      setDoc(initialDoc);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!clientRef.current) return;
    // 定期同步client的文档状态到UI
    const timer = setInterval(() => {
      const currentDoc = clientRef.current!.document || "";
      if (currentDoc !== prevDocRef.current) {
        setDoc(currentDoc);
        prevDocRef.current = currentDoc;
      }
    }, 100);
    return () => clearInterval(timer);
  }, []);

  const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    if (!clientRef.current) return;
    const newValue = e.target.value;
    // 使用client当前文档状态作为旧值
    const oldValue = clientRef.current.document || "";
    if (newValue !== oldValue) {
      // 生成操作集合
      const operations = generateOperations(oldValue, newValue);
      // 按顺序应用操作
      operations.forEach((op) => {
        clientRef.current!.applyClient(op);
      });
    }
  };

  const handleToggleSync = () => {
    const newValue = !enableSync;
    setEnableSync(newValue);
    if (clientRef.current) {
      clientRef.current.setEnableSync(newValue);
    }
  };

  return (
    <div style={{ border: "1px solid #ccc", padding: 10 }}>
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          marginBottom: 10,
        }}
      >
        <p style={{ margin: 0 }}>Document：</p>
        <label style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer" }}>
          <input type="checkbox" checked={enableSync} onChange={handleToggleSync} />
          <span>同步到服务端</span>
        </label>
      </div>
      <textarea value={doc} onChange={handleChange} rows={5} />
    </div>
  );
}

function App() {
  const [serverDoc, setServerDoc] = useState<string>("");

  useEffect(() => {
    const timer = setInterval(() => {
      setServerDoc(getDemoServerInstance().document || "");
    }, 100);
    return () => clearInterval(timer);
  }, []);

  return (
    <div>
      <div style={{ border: "1px solid #ccc", padding: 10, height: 100 }}>
        <p>Server Document:</p>
        <p>{serverDoc}</p>
      </div>
      <div style={{ display: "flex", gap: 10, marginTop: 20 }}>
        <Editor name="A" />
        <Editor name="B" />
      </div>
    </div>
  );
}

export default App;
