/* Main — 방사형 허브 + 배치 변형 */

/* ---- 업무영역 카드 내용 편집 저장소 (세이프스쿨 전용) ----------------
   기본값은 SS_DATA.AREAS, 편집분만 localStorage에 덮어쓰기로 보관 */
const SS_AREAS_KEY = "ss-areas-override-v1";
function loadAreaOverrides() {
  try { return JSON.parse(localStorage.getItem(SS_AREAS_KEY)) || {}; }
  catch (e) { return {}; }
}
function saveAreaOverrides(ov) {
  try { localStorage.setItem(SS_AREAS_KEY, JSON.stringify(ov)); } catch (e) {}
}
function mergeAreas(overrides) {
  return window.SS_DATA.AREAS.map((a) => {
    const o = overrides[a.id];
    return o ? { ...a, ...o } : a;
  });
}

/* ---- 카드별 보조 박스 (세이프스쿨이 사진/안내 입력 → 학교가 열람) ----
   내용이 비면 학교·미리보기에서는 아예 보이지 않음 */
const SS_EXTRA_KEY = "ss-area-extra-v1";
function loadAreaExtras() {
  try { return JSON.parse(localStorage.getItem(SS_EXTRA_KEY)) || {}; }
  catch (e) { return {}; }
}
function saveAreaExtras(ex) {
  try { localStorage.setItem(SS_EXTRA_KEY, JSON.stringify(ex)); } catch (e) {}
}
// 업로드 사진을 캔버스로 축소해 dataURL로 (localStorage 용량 보호)
function fileToScaledDataURL(file, maxW, cb) {
  const reader = new FileReader();
  reader.onload = () => {
    const img = new Image();
    img.onload = () => {
      const scale = Math.min(1, maxW / img.width);
      const w = Math.round(img.width * scale), h = Math.round(img.height * scale);
      const cv = document.createElement("canvas");
      cv.width = w; cv.height = h;
      cv.getContext("2d").drawImage(img, 0, 0, w, h);
      cb(cv.toDataURL("image/jpeg", 0.82));
    };
    img.src = reader.result;
  };
  reader.readAsDataURL(file);
}

function AreaExtra({ extra, editing, onText, onPhoto, onClearPhoto }) {
  const fileRef = useRef(null);
  const ex = extra || {};
  const hasContent = !!(ex.text || ex.img);

  const handleFile = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    fileToScaledDataURL(f, 720, (dataURL) => onPhoto(dataURL));
    e.target.value = "";
  };

  // 편집 모드가 아니면 — 내용이 있을 때만 노출 (학교 담당자 / 세이프스쿨 미리보기)
  if (!editing) {
    if (!hasContent) return null;
    return (
      <div className="area-extra">
        {ex.img && <img className="area-extra__img" src={ex.img} alt="" />}
        {ex.text && <p className="area-extra__text">{ex.text}</p>}
      </div>
    );
  }

  // 편집 모드 (세이프스쿨 전용) — 항상 입력 affordance 표시
  return (
    <div className="area-extra is-edit" onClick={(e) => e.stopPropagation()}>
      <div className="area-extra__label"><i data-lucide="image-plus"></i> 학교 안내 (선택)</div>
      {ex.img && (
        <div className="area-extra__photo">
          <img src={ex.img} alt="" />
          <button type="button" className="area-extra__rm" onClick={onClearPhoto} title="사진 제거">
            <i data-lucide="x"></i>
          </button>
        </div>
      )}
      <textarea className="area-extra__ta" rows={2} maxLength={140}
        value={ex.text || ""} placeholder="학교에 보여줄 안내 문구"
        onChange={(e) => onText(e.target.value)} />
      <button type="button" className="area-extra__add" onClick={() => fileRef.current && fileRef.current.click()}>
        <i data-lucide="image"></i> {ex.img ? "사진 변경" : "사진 추가"}
      </button>
      <input ref={fileRef} type="file" accept="image/*" hidden onChange={handleFile} />
    </div>
  );
}

function AreaInner({ area, badge, editing, onField }) {
  return (
    <React.Fragment>
      <span className={"area__badge" + (badge > 0 ? "" : " is-empty")} title={"미확인 로그 " + badge + "건"}>{badge > 99 ? "99+" : badge}</span>
      <div className="area__ic"><i data-lucide={area.icon}></i></div>
      {editing ? (
        <div className="area__edit" onClick={(e) => e.stopPropagation()}>
          <input className="area__edit-ttl" value={area.title} placeholder="제목"
            maxLength={20} onChange={(e) => onField("title", e.target.value)} />
          <input className="area__edit-sub" value={area.sub} placeholder="부제 (선택)"
            maxLength={20} onChange={(e) => onField("sub", e.target.value)} />
          <textarea className="area__edit-desc" value={area.desc} placeholder="설명" rows={2}
            maxLength={60} onChange={(e) => onField("desc", e.target.value)} />
        </div>
      ) : (
        <React.Fragment>
          <div className="area__ttl">{(area.no ? area.no + ". " : "") + (area.sub ? area.title + " " + area.sub : area.title)}</div>
          <div className="area__desc">{area.desc}</div>
        </React.Fragment>
      )}
      {area.active
        ? <span className="area__chip go">바로가기 <i data-lucide="arrow-right"></i></span>
        : <span className="area__chip soon"><i data-lucide="clock"></i> 준비중</span>}
    </React.Fragment>
  );
}

function BrandCenter({ variant, canAdmin, locked, onClick }) {
  const C = window.SS_DATA.COMPANY;
  const A = window.SS_DATA.ADMIN;
  const arrow = <svg className="cc-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg>;
  const lock = <svg className="cc-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect width="18" height="11" x="3" y="11" rx="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>;
  const base = variant === "radial" ? "radial__center" : "hub-center-card";
  const cls = base + (canAdmin ? " is-btn" : "") + (locked ? " is-locked" : "");
  const foot = canAdmin
    ? <span className="center-cta">관리자 대시보드 {arrow}</span>
    : locked
      ? <span className="center-lock">{lock} 세이프스쿨 전용</span>
      : <span className="tag">{C.tagline}</span>;
  return (
    <button className={cls} onClick={onClick} type="button">
      <img className="shield" src="assets/logo-shield-ss.svg" alt="" />
      <div className="ttl">세이프스쿨</div>
      {canAdmin && <span className="center-live"><span className="live-dot xs"></span> 접속 {A.onlineCount}개교</span>}
      {foot}
    </button>
  );
}

function MainHub({ onOpenArea, onCenterClick, role, layout, loggedIn, unread, hireNew, toast }) {
  useLucideSS();
  const C = window.SS_DATA.COMPANY;

  const canAdmin = loggedIn && role === "safe";

  // ---- 업무영역 카드 편집 (세이프스쿨 전용) ----
  const [overrides, setOverrides] = useState(loadAreaOverrides);
  const [editing, setEditing] = useState(false);
  const AREAS = mergeAreas(overrides);

  // 권한을 잃으면 편집 모드 자동 종료 (학교 역할/로그아웃)
  useEffect(() => { if (!canAdmin && editing) setEditing(false); }, [canAdmin, editing]);

  const updateField = (id, field, value) => {
    setOverrides((prev) => {
      const base = window.SS_DATA.AREAS.find((a) => a.id === id) || {};
      const next = { ...prev, [id]: { ...prev[id], [field]: value } };
      // 기본값과 동일해지면 해당 오버라이드 정리
      const merged = { title: base.title, sub: base.sub, desc: base.desc, ...next[id] };
      if (merged.title === base.title && merged.sub === base.sub && merged.desc === base.desc) {
        delete next[id];
      } else {
        next[id] = merged;
      }
      saveAreaOverrides(next);
      return next;
    });
  };
  const resetAreas = () => { setOverrides({}); saveAreaOverrides({}); if (toast) toast("업무영역 카드를 기본값으로 되돌렸습니다"); };
  const finishEditing = () => { setEditing(false); if (toast) toast("업무영역 카드 내용이 저장되었습니다"); };

  // ---- 카드별 보조 박스 (세이프스쿨 입력 → 학교 열람) ----
  const [extras, setExtras] = useState(loadAreaExtras);
  const updateExtra = (id, field, value) => {
    setExtras((prev) => {
      const cur = { ...(prev[id] || {}) };
      if (value) cur[field] = value; else delete cur[field];
      const next = { ...prev };
      if (cur.text || cur.img) next[id] = cur; else delete next[id];
      saveAreaExtras(next);
      return next;
    });
  };

  const openIf = (a) => { if (editing) return; if (a.active) onOpenArea(a); };
  const cls = (a) => "area " + (a.active ? "is-active" : "is-disabled") + (editing ? " is-editing" : "");
  const badgeOf = (a) => {
    if (!loggedIn) return 0;
    if (a.id === "facility") return unread || 0;
    if (a.id === "substitute") return hireNew || 0;
    return 0;
  };
  const centerProps = { canAdmin, locked: !canAdmin, onClick: onCenterClick };

  // 카드 + 보조 박스를 한 묶음(.area-cell)으로 렌더 — 모든 레이아웃 공용
  // sideClass: 보조 박스를 카드의 어느 방향에 둘지 (방사형에서 중앙 원/이웃을 안 가리게)
  const renderCell = (a, style, sideClass) => (
    <div key={a.id} className={"area-cell " + (sideClass || "box-bottom")} style={style}>
      <div className={cls(a)} onClick={() => openIf(a)}>
        <AreaInner area={a} badge={badgeOf(a)} editing={editing} onField={(f, v) => updateField(a.id, f, v)} />
      </div>
      <AreaExtra extra={extras[a.id]} editing={editing}
        onText={(v) => updateExtra(a.id, "text", v)}
        onPhoto={(d) => updateExtra(a.id, "img", d)}
        onClearPhoto={() => updateExtra(a.id, "img", "")} />
    </div>
  );

  // 방사형 — 카드 위치(시계 12시부터 시계방향)와 보조 박스 방향
  //  0 위, 1·2 오른쪽, 3 아래, 4·5 왼쪽
  const RADIAL_SIDE = ["box-top", "box-right", "box-right", "box-bottom", "box-left", "box-left"];

  // ---- 방사형 위치 계산 ---- (보조 박스가 바깥으로 뻗을 공간을 위해 반경 축소)
  const positions = AREAS.map((_, i) => {
    const ang = (-90 + i * 60) * Math.PI / 180;
    return { x: 50 + 26 * Math.cos(ang), y: 50 + 24 * Math.sin(ang) };
  });

  return (
    <div className="page hub screen-enter">

      {canAdmin && (
        <div className={"hub__editbar" + (editing ? " is-on" : "")}>
          {editing ? (
            <React.Fragment>
              <span className="hub__editbar-hint"><i data-lucide="pencil-line"></i> 카드 내용·학교 안내를 수정하세요</span>
              <button className="btn btn-ghost btn-sm" onClick={resetAreas} type="button"><i data-lucide="rotate-ccw"></i> 기본값 복원</button>
              <button className="btn btn-primary btn-sm" onClick={finishEditing} type="button"><i data-lucide="check"></i> 편집 완료</button>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <span className="hub__editbar-hint"><i data-lucide="shield-check"></i> 세이프스쿨 전용 — 카드 내용 편집</span>
              <button className="btn btn-ghost btn-sm" onClick={() => setEditing(true)} type="button"><i data-lucide="pencil"></i> 내용 편집</button>
            </React.Fragment>
          )}
        </div>
      )}

      {layout === "radial" && (
        <div className="radial">
          <svg className="radial__spokes" viewBox="0 0 100 100" preserveAspectRatio="none">
            {positions.map((p, i) => (
              <line key={i} x1="50" y1="50" x2={p.x} y2={p.y}
                stroke={AREAS[i].active ? "var(--blue-400)" : "var(--gray-200)"}
                strokeWidth="1.5" strokeDasharray={AREAS[i].active ? "0" : "4 4"}
                vectorEffect="non-scaling-stroke" />
            ))}
          </svg>
          <BrandCenter variant="radial" {...centerProps} />
          {AREAS.map((a, i) => renderCell(a, { left: positions[i].x + "%", top: positions[i].y + "%" }, RADIAL_SIDE[i]))}
        </div>
      )}

      {layout === "columns" && (
        <div className="hub-cols">
          <div className="hub-col">
            {[0, 1, 2].map((i) => renderCell(AREAS[i]))}
          </div>
          <BrandCenter variant="card" {...centerProps} />
          <div className="hub-col">
            {[3, 4, 5].map((i) => renderCell(AREAS[i]))}
          </div>
        </div>
      )}

      {layout === "stack" && (
        <div className="hub-stack">
          <div className="hub-row">
            {[0, 1, 2].map((i) => renderCell(AREAS[i]))}
          </div>
          <BrandCenter variant="card" {...centerProps} />
          <div className="hub-row">
            {[3, 4, 5].map((i) => renderCell(AREAS[i]))}
          </div>
        </div>
      )}

      <div className="hub__footer">
        <span className="fitem"><i data-lucide="map-pin"></i> <b>{C.address}</b></span>
        <span className="fitem"><i data-lucide="phone"></i> Tel <b>{C.tel}</b></span>
        <span className="fitem"><i data-lucide="printer"></i> FAX <b>{C.fax}</b></span>
        <span className="fitem"><i data-lucide="mail"></i> <b>{C.email}</b></span>
      </div>
    </div>
  );
}

window.MainHub = MainHub;
window.AreaExtra = AreaExtra;
window.fileToScaledDataURL = fileToScaledDataURL;
