/* 신도랑 라인업 — App 루트 (관리자 모드 / 저장) */
const { useState, useEffect, useRef, useCallback } = React;

/* 경로 기반 불변 업데이트: "modes.rental.cards.0.price" */
function setByPath(obj, path, value) {
  const keys = path.split(".");
  const clone = Array.isArray(obj) ? [...obj] : { ...obj };
  let cur = clone;
  for (let i = 0; i < keys.length - 1; i++) {
    const k = keys[i];
    const next = cur[k];
    cur[k] = Array.isArray(next) ? [...next] : { ...next };
    cur = cur[k];
  }
  cur[keys[keys.length - 1]] = value;
  return clone;
}

function uid() { return "c" + Math.random().toString(36).slice(2, 8); }

function App() {
  const [data, setData] = useState(null);
  const [mode, setMode] = useState("rental");
  const [editing, setEditing] = useState(false);
  const [authed, setAuthed] = useState(false);
  const [pwOpen, setPwOpen] = useState(false);
  const [popup, setPopup] = useState(false);
  const [dirty, setDirty] = useState(false);
  const [toast, setToast] = useState("");
  const original = useRef(null);

  useEffect(() => {
    LineupService.init();
    LineupService.load().then((d) => { setData(d); original.current = JSON.stringify(d); });
  }, []);

  const flash = (msg) => { setToast(msg); setTimeout(() => setToast(""), 2200); };

  const onEdit = useCallback((path, value) => {
    setData((d) => setByPath(d, path, value));
    setDirty(true);
  }, []);

  const enterAdmin = () => { setPwOpen(true); };
  const onAuth = () => { setAuthed(true); setEditing(true); setPwOpen(false); };

  const exitAdmin = () => {
    if (dirty && !confirm("저장하지 않은 변경사항이 있습니다. 편집을 종료할까요?")) return;
    if (dirty) { setData(JSON.parse(original.current)); setDirty(false); }
    LineupService.signOut();
    setEditing(false); setAuthed(false);
  };

  const save = async () => {
    try {
      await LineupService.save(data);
      original.current = JSON.stringify(data);
      setDirty(false);
      flash("저장되었습니다 (" + LineupService.backend() + ")");
    } catch (e) {
      flash("저장 실패: " + e.message);
    }
  };

  const resetDefault = () => {
    if (!confirm("기본 콘텐츠로 초기화할까요? (저장 전까지는 되돌릴 수 있습니다)")) return;
    setData(JSON.parse(JSON.stringify(window.DEFAULT_DATA)));
    setDirty(true);
  };

  const addCard = (pos) => {
    setData((d) => {
      const cards = d.modes[mode].cards;
      const nc = { id: uid(), pos, category: "새 카테고리", name: "신규 모델", desc: "", price: "0원~", accent: "#4f63e0", connector: "라벨" };
      return setByPath(d, `modes.${mode}.cards`, [...cards, nc]);
    });
    setDirty(true);
  };

  const deleteCard = (id) => {
    setData((d) => {
      const cards = d.modes[mode].cards.filter((c) => c.id !== id);
      return setByPath(d, `modes.${mode}.cards`, cards);
    });
    setDirty(true);
  };

  if (!data) {
    return <div style={{ textAlign: "center", padding: "120px 20px", color: "#9aa0ba", fontWeight: 700 }}>불러오는 중…</div>;
  }

  return (
    <React.Fragment>
      {/* 관리자 진입 버튼 */}
      {!authed && (
        <button className="admin-fab" title="관리자 모드" onClick={enterAdmin} aria-label="관리자 모드">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
        </button>
      )}

      {/* 관리자 바 */}
      {authed && (
        <div className="adminbar">
          <span className="dot"></span>
          <b>관리자 모드</b>
          <span className="be">저장소: {LineupService.backend()} · 현재 탭: {data.modes[mode].label}</span>
          <span className="spacer"></span>
          <button className="btn btn-ghost sm" onClick={resetDefault}>초기화</button>
          <button className="btn btn-primary sm" onClick={save} disabled={!dirty} style={{ opacity: dirty ? 1 : .5 }}>저장{dirty ? " •" : ""}</button>
          <button className="btn btn-danger sm" onClick={exitAdmin}>종료</button>
        </div>
      )}

      <div className={"wrap" + (authed ? " with-adminbar" : "")} data-editing={editing}>
        <header className="head">
          <Edit path="eyebrow" value={data.eyebrow} onEdit={onEdit} editing={editing} tag="p" className="eyebrow" />
          <Edit path="title" value={data.title} onEdit={onEdit} editing={editing} tag="h1" className="title" />
        </header>

        <ModeToggle data={data} mode={mode} setMode={setMode} />

        <Board data={data} mode={mode} editing={editing} onEdit={onEdit}
          onOpenPopup={() => setPopup(true)} onAddCard={addCard} onDeleteCard={deleteCard} />
      </div>

      {popup && (
        <ServicePopup data={data.popup} center={data.modes[mode].center} editing={editing}
          onClose={() => setPopup(false)} onEdit={onEdit} />
      )}

      {pwOpen && <PasswordModal onClose={() => setPwOpen(false)} onAuth={onAuth} />}

      <div className={"toast" + (toast ? " show" : "")}>{toast}</div>
    </React.Fragment>
  );
}

function PasswordModal({ onClose, onAuth }) {
  const usesAuth = LineupService.usesAuth();
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [err, setErr] = useState("");
  const [busy, setBusy] = useState(false);
  const ref = useRef(null);
  useEffect(() => { ref.current && ref.current.focus(); }, []);
  const submit = () => {
    if (busy) return;
    setBusy(true); setErr("");
    LineupService.signIn(email.trim(), pw)
      .then(() => onAuth())
      .catch((e) => {
        setBusy(false);
        const code = e && e.code;
        if (code === "auth/invalid-email") setErr("이메일 형식이 올바르지 않습니다.");
        else if (code === "auth/invalid-credential" || code === "auth/wrong-password" || code === "auth/user-not-found")
          setErr("이메일 또는 비밀번호가 올바르지 않습니다.");
        else if (code === "auth/too-many-requests") setErr("시도가 너무 많습니다. 잠시 후 다시 시도하세요.");
        else setErr(e.message || "로그인에 실패했습니다.");
        setPw("");
      });
  };
  return (
    <div className="overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal pw-modal">
        <h3>관리자 로그인</h3>
        <p>{usesAuth ? "관리자 계정으로 로그인하면 콘텐츠를 편집할 수 있어요." : "비밀번호를 입력하면 콘텐츠를 편집할 수 있어요."}</p>
        {usesAuth && (
          <input ref={ref} type="email" value={email} placeholder="이메일"
            onChange={(e) => { setEmail(e.target.value); setErr(""); }}
            onKeyDown={(e) => e.key === "Enter" && submit()} />
        )}
        <input ref={usesAuth ? null : ref} type="password" value={pw} placeholder="비밀번호"
          onChange={(e) => { setPw(e.target.value); setErr(""); }}
          onKeyDown={(e) => e.key === "Enter" && submit()} />
        {err && <div className="err">{err}</div>}
        <div className="row">
          <button className="btn btn-ghost" onClick={onClose} disabled={busy}>취소</button>
          <button className="btn btn-primary" onClick={submit} disabled={busy}>{busy ? "확인 중…" : "로그인"}</button>
        </div>
      </div>
    </div>
  );
}

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