// Initial mock data — copied/expanded from lib-data.jsx
// Spaces, sessions, documents, history are all mutable through the reducer.

const SPACES_INIT = [
  { id: "work",    name: "일",       dot: "#3A6EE0", description: "프로덕트, 회의, 분기 리뷰" },
  { id: "health",  name: "건강",     dot: "#3E9E72", description: "운동, 수면, 식단" },
  { id: "writing", name: "글쓰기",   dot: "#C68B3E", description: "에세이, 메모, 문장 연습" },
  { id: "reading", name: "독서",     dot: "#7A5BB8", description: "읽은 책, 메모, 인용" },
  { id: "ideas",   name: "아이디어", dot: "#C5524C", description: "잡다한 떠오름" },
];

const PALETTE_OPTIONS = [
  "#3A6EE0", "#3E9E72", "#C68B3E", "#7A5BB8", "#C5524C",
  "#5C8AA8", "#A8865C", "#6B7A5C", "#B85C8A",
];

// Default (volatile) chat — disappears on refresh; never persisted to docs
const DEFAULT_CHAT_INIT = [
  { id: "d1", role: "user", text: "아 오늘 회의 좀 답답했다. 같은 얘기 세 번째 도는 느낌." },
  { id: "d2", role: "ai",   text: "어떤 부분이 반복되는 느낌이었어요?" },
  { id: "d3", role: "user", text: "결정해야 할 사람이 결정을 안 해. 모든 선택지를 열어두려고 하니까 회의가 끝나도 진전이 없음." },
  { id: "d4", role: "ai",   text: "그건 일 공간으로 옮겨두면 다음에 비슷한 회의 잡힐 때 맥락이 될 것 같은데, 지금은 그대로 두실래요?" },
  { id: "d5", role: "user", text: "응 그냥 잡담. 옮기지 마." },
  { id: "d6", role: "ai",   text: "알겠어요." },
];

// Document bodies (rich content, blocks)
const DOC_BODIES = {
  "frame": [
    { type: "h2", text: "왜 이 프레임을 쓰는가" },
    { type: "p",  text: "분기마다 같은 형식으로 정리해두면, 다음 분기와 비교가 쉽다. 세 칸짜리 표보다 글로 풀어 쓰는 게 더 잘 남는다는 걸 지난번에 확인했다. [분기별 리뷰 — 23Q4](#doc:q4-review)에서 한 번 실험해보고 이 형식으로 굳어가는 중." },
    { type: "h2", text: "1. 무엇이 달라졌나" },
    { type: "p",  text: "지표가 아니라 행동의 변화부터 적는다. 숫자는 행동의 증거로 끌어온다 — 반대 방향으로 시작하면 자기 합리화가 된다." },
    { type: "ul", items: [
      "이번 분기 가장 큰 행동 변화 1–2개",
      "그 행동을 뒷받침하는 지표 (있다면)",
      "행동 변화가 없으면 “없음”이라고 적는다",
    ]},
    { type: "h2", text: "2. 우리가 만든 변화인가, 외부 요인인가" },
    { type: "p",  text: "가장 헷갈리는 부분. 분리가 안 되면 일단 “모르겠음”으로 적고 다음 분기에 검증 방법을 붙인다. 이번 분기 대표 사례: [검색 사용량 급증 원인 가설](#doc:search-hypo)." },
    { type: "callout", text: "[검색 사용량 급증 원인 가설](#doc:search-hypo)을 따로 두고 거기서 검증을 진행한다. 회의에서 본 결정 지연은 [회의 — 결정권자 부재 패턴](#doc:meeting-pattern)으로 옮겨뒀다." },
    { type: "h2", text: "3. 다음 분기에 들고 갈 가설" },
    { type: "p",  text: "한 분기에 가설 3개를 넘기지 않는다. 4개부터는 어차피 검증 못 한다. 우선순위 잡는 법은 [OKR 작성 시 자주 빠뜨리는 것](#doc:okr-pitfalls) 참고." },
  ],
  "search-hypo": [
    { type: "p", text: "이번 분기 검색 사용량이 약 2배로 늘었다. 우리가 만든 변화 때문인지, 외부 유입 변화 때문인지 분리가 안 된다. 사용자 관찰은 [검색 — 사용자 인터뷰 노트](#doc:search-interviews)에 모아둠." },
    { type: "h2", text: "검증 후보" },
    { type: "ul", items: [
      "코호트를 가입 시점으로 자르고 행동 변화량 비교",
      "쿼리 길이 분포가 달라졌는지 확인",
      "기능 출시 시점 ±2주 윈도우",
    ]},
    { type: "h2", text: "밖에서 들어온 관점" },
    { type: "p", text: "[독서 — 알고리즘과 발견](#doc:algo-discovery)의 ‘검색은 발견의 반대편에 있다’ 문장이 새 가설을 줬다 — 사용자가 ‘무엇을 찾으려 했는가’를 더 자세히 봐야 할지도. [검색하면서 떠오른 글감](#doc:writing-from-search)도 같은 결." },
  ],
  "meeting-pattern": [
    { type: "p", text: "결정권자가 빠진 회의는 같은 얘기를 세 번 돈다. 누가 결정할지를 먼저 정하지 않으면 어떤 진행도 어렵다." },
    { type: "h2", text: "관찰" },
    { type: "p", text: "최근 3개 회의 모두 결정권자가 “더 들어보고 정하자”로 끝났다. [팀 1on1 메모](#doc:1on1-memo)에서도 \"결정권자 부재\" 항목이 반복적으로 올라온다 (잠금 문서). [분기별 리뷰 — 23Q4](#doc:q4-review)에서 이미 한 번 짚었던 문제." },
  ],
  "onboarding-metrics": [
    { type: "h2", text: "활성화의 정의" },
    { type: "p", text: "활성화 = 첫 주 안에 핵심 행동을 4회 이상 수행한 상태." },
    { type: "p", text: "핵심 행동은 분기마다 다시 정의한다 — 한 번 정해두고 안 보면 의미가 없다." },
  ],
  "1on1-memo": [
    { type: "h2", text: "한 달 단위로 묻는 질문 세 가지" },
    { type: "ul", items: [
      "지난 한 달 가장 잘 풀린 것 / 가장 답답했던 것",
      "다음 한 달에 가장 신경 쓰고 싶은 사람·일",
      "내가 더 잘했으면 하는 동료의 행동 하나",
    ]},
    { type: "h2", text: "운영 원칙" },
    { type: "p", text: "메모는 회의 직후가 아니라 다음 1on1 직전에 정리한다. 시간이 좀 지나야 패턴이 보인다." },
    { type: "p", text: "공유는 본인 부분만, 본인 동의 후에. 자동 변경은 받지 않는다 — 이 문서를 잠가둔 이유." },
  ],
  "q4-review": [
    { type: "p", text: "지난 분기는 가설이 너무 많았다. 다섯 개 중 두 개만 검증." },
    { type: "h2", text: "넘겨준 것" },
    { type: "p", text: "검색 개선 가설, OKR 정합성 가설 두 개를 다음 분기로. 다음 작성은 [분기 리뷰 작성 프레임](#doc:frame) 형식대로, [OKR 작성 시 자주 빠뜨리는 것](#doc:okr-pitfalls)을 미리 살피고." },
  ],
  "search-interviews": [
    { type: "p", text: "사용자 5명 중 3명이 검색 결과 정렬 옵션이 안 보인다고 함." },
    { type: "h2", text: "공통 코멘트" },
    { type: "ul", items: ["최신순/관련순 토글 위치", "필터 기억 안 됨", "검색어 자동완성 부재"] },
  ],
  "okr-pitfalls": [
    { type: "h2", text: "OKR 작성 시 자주 빠뜨리는 것" },
    { type: "p", text: "측정 가능성보다 중요도가 먼저다. 측정 가능하지만 안 중요한 일을 지표로 잡으면 한 분기를 잃는다. 이 원칙은 [분기 리뷰 작성 프레임](#doc:frame)의 3번 가설 섹션과 연결되고, [분기별 리뷰 — 23Q4](#doc:q4-review)에서 실패한 두 가설이 정확히 이 함정." },
  ],
  "caffeine": [
    { type: "p", text: "오후 3시 이후 카페인은 그날 입면에 분명히 영향을 준다. [런닝 페이스 기록](#doc:running)이랑 같이 보면 운동한 날과 안 한 날 차이도 비교 가능." },
    { type: "h2", text: "주간 기록" },
    { type: "ul", items: ["월: 200mg / 입면 25분", "화: 0mg / 입면 8분", "수: 100mg / 입면 12분"] },
  ],
  "running": [
    { type: "p", text: "5km 페이스가 5'40\"/km 로 안정됨. 다음 목표는 인터벌 추가. 카페인 의존도는 [카페인 섭취와 수면](#doc:caffeine)에 같이 기록 중." },
  ],
  "back-pain": [
    { type: "p", text: "장시간 앉기 + 가방 한쪽 메기가 트리거인 듯. 다음 주는 가방 좌우 번갈아." },
  ],
  "essay-distance": [
    { type: "h2", text: "거리에 대하여" },
    { type: "p", text: "가까움은 거리의 부재가 아니라 거리를 견디는 방식이다. [메모: 무라카미 인터뷰](#doc:murakami)에서 출발한 문장. [문장 짧게 쓰는 연습](#doc:short-sentences)에 후속 메모." },
  ],
  "short-sentences": [
    { type: "h2", text: "문장을 짧게 쓴다는 것" },
    { type: "p", text: "끊을 곳을 찾는 것보다 이을 곳을 줄이는 것이다. [에세이 — 거리에 대하여](#doc:essay-distance) 도입부에 이 원칙으로 다시 깎아봤다." },
  ],
  "murakami": [
    { type: "p", text: "달리기에 대해 말할 때 — 한 시간 일찍 자고 한 시간 일찍 일어난다." },
  ],
  "algo-discovery": [
    { type: "p", text: "검색은 발견의 반대편에 있다고 한 문장. 다시 읽어보고 메모. 이 관점이 [검색 사용량 급증 원인 가설](#doc:search-hypo)에 새 가설을 줬다. [검색하면서 떠오른 글감](#doc:writing-from-search)에서는 비슷한 직관을 다른 문장으로 쓰고 있음." },
  ],
  "writing-from-search": [
    { type: "p", text: "정보를 찾는 행위 자체가 글의 소재가 된다 — 무엇을 찾으려 했는지가 더 흥미롭다. 일 쪽에서 보는 [검색 사용량 급증 원인 가설](#doc:search-hypo)과 같은 현상을 글쓰기 쪽에서는 다르게 부른다. [독서 — 알고리즘과 발견](#doc:algo-discovery)의 메모와 같이 두면 한 묶음." },
  ],
};

// Documents (id → {title, spaceId, updated, body, locked, links, autoReflected, isNew})
const DOCS_INIT = [
  { id: "frame",            title: "분기 리뷰 작성 프레임",       spaceId: "work",    updated: "방금",  body: DOC_BODIES["frame"], autoReflected: true,  tags: ["프레임", "분기"], size: "1.4k자" },
  { id: "search-hypo",      title: "검색 사용량 급증 원인 가설",  spaceId: "work",    updated: "방금",  body: DOC_BODIES["search-hypo"], autoReflected: true, tags: ["가설"], size: "820자" },
  { id: "meeting-pattern",  title: "회의 — 결정권자 부재 패턴",   spaceId: "work",    updated: "방금",  body: DOC_BODIES["meeting-pattern"], autoReflected: true, isNew: true, tags: ["패턴", "회의"], size: "240자" },
  { id: "onboarding-metrics", title: "온보딩 지표 정의",          spaceId: "work",    updated: "어제",  body: DOC_BODIES["onboarding-metrics"], tags: ["지표"], size: "1.1k자" },
  { id: "1on1-memo",        title: "팀 1on1 메모",                 spaceId: "work",    updated: "3일 전", body: DOC_BODIES["1on1-memo"], locked: true, tags: ["개인"], size: "2.3k자" },
  { id: "q4-review",        title: "분기별 리뷰 — 23Q4",          spaceId: "work",    updated: "지난주", body: DOC_BODIES["q4-review"], tags: ["분기","회고"], size: "3.8k자" },
  { id: "search-interviews",title: "검색 — 사용자 인터뷰 노트",   spaceId: "work",    updated: "지난주", body: DOC_BODIES["search-interviews"], tags: ["인터뷰"], size: "1.9k자" },
  { id: "okr-pitfalls",     title: "OKR 작성 시 자주 빠뜨리는 것", spaceId: "work",   updated: "지난달", body: DOC_BODIES["okr-pitfalls"], tags: ["프레임"], size: "640자" },

  { id: "caffeine",         title: "카페인 섭취와 수면",            spaceId: "health",  updated: "오늘",  body: DOC_BODIES["caffeine"], tags: ["수면"], size: "560자" },
  { id: "running",          title: "런닝 페이스 기록",              spaceId: "health",  updated: "어제",  body: DOC_BODIES["running"], tags: ["운동"], size: "320자" },
  { id: "back-pain",        title: "허리 통증 트리거",              spaceId: "health",  updated: "2일 전", body: DOC_BODIES["back-pain"], locked: true, tags: ["관찰"], size: "180자" },

  { id: "essay-distance",   title: "에세이 — 거리에 대하여",        spaceId: "writing", updated: "30분 전", body: DOC_BODIES["essay-distance"], tags: ["에세이"], size: "1.8k자" },
  { id: "short-sentences",  title: "문장 짧게 쓰는 연습",           spaceId: "writing", updated: "어제",  body: DOC_BODIES["short-sentences"], tags: ["연습"], size: "420자" },
  { id: "murakami",         title: "메모: 무라카미 인터뷰",         spaceId: "writing", updated: "지난주", body: DOC_BODIES["murakami"], tags: ["메모"], size: "260자" },
  { id: "writing-from-search", title: "검색하면서 떠오른 글감",     spaceId: "writing", updated: "그제",  body: DOC_BODIES["writing-from-search"], tags: ["글감"], size: "180자" },

  { id: "algo-discovery",   title: "독서 — 알고리즘과 발견",        spaceId: "reading", updated: "지난주", body: DOC_BODIES["algo-discovery"], tags: ["메모"], size: "240자" },
];

// Sessions per space
const SESSIONS_INIT = {
  work: [
    { id: "qreview",     title: "분기 리뷰 준비",          turns: 5,  when: "방금",   active: true, docsTouched: 3, messages: [
        { id: "w1", role: "user", text: "분기 리뷰 준비 시작. 이번 분기 가장 큰 변화부터 적어볼게." },
        { id: "w2", role: "ai",   text: "「분기 리뷰 작성 프레임」을 맥락으로 가져왔어요. 어디부터 시작할까요?" },
        { id: "w3", role: "user", text: "검색 사용량이 2배 늘었는데 그게 우리가 만든 변화인지 외부 요인인지 분리가 안 됨. 그리고 보면서 떠올랐는데 — 회의에서 결정권자가 계속 빠지는 패턴 있어. 그것도 따로 정리해두고 싶음.",
          reflections: [
            { doc: "분기 리뷰 작성 프레임",     docId: "frame",           kind: "update" },
            { doc: "검색 사용량 급증 원인 가설", docId: "search-hypo",     kind: "update" },
            { doc: "회의 — 결정권자 부재 패턴",  docId: "meeting-pattern", kind: "create" },
          ],
        },
        { id: "w4", role: "ai",   text: "세 곳에 나눠 적어뒀어요. 회의 패턴은 새 문서로 시작했습니다 — 제목 바꾸려면 우측에서." },
        { id: "w5", role: "user", text: "좋아. 그리고 다음 분기 가설은 세 개 넘기지 않는다는 규칙도 다시 강조." },
    ]},
    { id: "onboard",  title: "신입 온보딩 메모",        turns: 18, when: "어제",   docsTouched: 2, messages: [
        { id: "o1", role: "user", text: "이번 신입 두 명, 첫 주에 어디서 막힐 것 같아?" },
        { id: "o2", role: "ai",   text: "온보딩 지표 정의 문서를 가져왔어요. 첫 주 핵심 행동은 4회 이상으로 잡혀 있네요." },
    ]},
    { id: "decision", title: "결정권자 부재 패턴 탐구", turns: 12, when: "3일 전", docsTouched: 1, note: "→ 회의 문서로 발전", messages: [] },
    { id: "search-ux",title: "검색 UX 인터뷰 정리",     turns: 24, when: "지난주", docsTouched: 4, messages: [] },
    { id: "okr",      title: "OKR 작성 워밍업",         turns: 7,  when: "지난주", docsTouched: 0, note: "정리할 만한 게 없었음", messages: [] },
    { id: "qreview-prev", title: "23Q4 리뷰 준비",     turns: 31, when: "지난달", docsTouched: 5, messages: [] },
  ],
  health: [
    { id: "sleep", title: "수면 점검", turns: 3, when: "어제", active: true, docsTouched: 1, messages: [
        { id: "h1", role: "user", text: "요새 자꾸 새벽에 깬다. 어제 카페인 얼마나 마셨더라" },
        { id: "h2", role: "ai", text: "카페인 섭취와 수면 문서에 어제 200mg / 입면 25분으로 적어두셨어요." },
    ]},
  ],
  writing: [
    { id: "distance", title: "에세이 — 거리에 대하여 (작업 중)", turns: 14, when: "30분 전", active: true, docsTouched: 1, messages: [
        { id: "wr1", role: "user", text: "‘가까움은 거리의 부재가 아니다’로 시작하는 문단을 다듬고 싶어." },
    ]},
  ],
  reading: [
    { id: "algo", title: "알고리즘과 발견 메모", turns: 4, when: "지난주", active: true, docsTouched: 1, messages: [] },
  ],
  ideas: [],
};

// History (auto-organize ledger)
const HISTORY_INIT = [
  { id: "h-1", time: "방금",  spaceId: "work",   action: "create",  docId: "meeting-pattern", title: "회의 — 결정권자 부재 패턴", detail: "새 문서 생성 — “결정해야 할 사람이 결정을 안 해” 패턴", undoable: true,  why: "기존 문서 어느 곳에도 들어맞지 않는 새로운 패턴으로 판단했어요. 회의·결정 관련 문서가 없어 새 문서를 만들었습니다." },
  { id: "h-2", time: "방금",  spaceId: "work",   action: "update",  docId: "search-hypo",     title: "검색 사용량 급증 원인 가설", detail: "‘내부/외부 요인 분리’ 항목 추가", undoable: true, why: "기존 문서의 ‘검증 후보’ 섹션에 명확히 들어맞아 추가했습니다." },
  { id: "h-3", time: "방금",  spaceId: "work",   action: "update",  docId: "frame",           title: "분기 리뷰 작성 프레임", detail: "‘우리가 만든 변화인가’ 섹션에 사례 추가", undoable: true, why: "프레임 문서의 ‘2번 섹션’에 직접 해당하는 사례라 추가했습니다." },
  { id: "h-4", time: "3분 전", spaceId: "work",  action: "skip",                              title: "현재 턴 — 의미 있는 변경 없음", detail: "“좋아. 강조해줘”는 동의 응답이라 새 정보가 없다고 판단해 넘어갔습니다.", undoable: false, why: "사용자의 메시지가 새로운 정보를 담고 있지 않다고 판단했어요. 동의·맞장구는 보통 문서화하지 않습니다." },
  { id: "h-5", time: "10분 전", spaceId: "health", action: "update", docId: "caffeine",       title: "카페인 섭취와 수면", detail: "어제 섭취량/취침 시간 기록 추가", undoable: true, why: "주간 기록 섹션에 일일 기록이 누적되어 있어 같은 패턴으로 추가했습니다." },
  { id: "h-6", time: "어제",    spaceId: "writing", action: "merge", docId: "essay-distance", title: "에세이 — 거리에 대하여", detail: "두 개의 메모를 한 문서로 병합", undoable: true, why: "두 메모가 거의 같은 주제를 다루고 있어 하나로 합쳤습니다." },
  { id: "h-7", time: "어제",    spaceId: "work",   action: "update", docId: "onboarding-metrics", title: "온보딩 지표 정의", detail: "‘활성화’ 정의 수정", undoable: true, why: "기존 정의가 모호하다는 사용자 메시지에 따라 4회/주로 명확히 했습니다." },
  { id: "h-8", time: "3일 전",  spaceId: "work",   action: "create", docId: "1on1-memo",       title: "팀 1on1 메모", detail: "새 문서 생성 — 이후 잠금됨", undoable: false, why: "1on1 관련 문서가 없어 새로 만들었어요. 이후 직접 잠그셨습니다." },
];

// Triggered scripted AI responses by exact match (or substring) of user text in space chat
// Each item: trigger (string), reply (text), reflections (list of doc id+kind+change description)
const SCRIPTS = {
  work: [
    {
      match: ["분기 가설은 세 개", "세 개 넘기지", "3개 넘", "가설 3개"],
      reply: "프레임 문서에 강조 콜아웃으로 다시 적어두었어요. 다음 분기 작성 시 자동으로 맥락에 들어옵니다.",
      reflections: [
        { docId: "frame", kind: "update", change: "‘3. 다음 분기에 들고 갈 가설’ 콜아웃 추가" },
      ],
    },
    {
      match: ["검색 코호트", "코호트", "코호트로 분리"],
      reply: "검색 가설 문서의 ‘검증 후보’ 첫 항목을 ‘가입 시점 코호트로 분리’로 구체화했어요.",
      reflections: [
        { docId: "search-hypo", kind: "update", change: "‘검증 후보’ 첫 항목 구체화" },
      ],
    },
    {
      match: ["회의에서 누가 결정", "결정권자를 정해", "결정 책임자"],
      reply: "회의 문서에 ‘결정 책임자 사전 합의’ 원칙을 새 섹션으로 추가했어요.",
      reflections: [
        { docId: "meeting-pattern", kind: "update", change: "‘결정 책임자 사전 합의’ 섹션 추가" },
      ],
    },
  ],
  health: [
    {
      match: ["카페인", "커피"],
      reply: "카페인 문서에 오늘 기록 슬롯을 비워두고 잠시 후에 시간을 채워달라고 알림 걸어둘게요.",
      reflections: [ { docId: "caffeine", kind: "update", change: "오늘자 기록 슬롯 추가" } ],
    },
  ],
  writing: [
    {
      match: ["가까움", "거리"],
      reply: "에세이 본문의 도입 문단을 두 가지 버전으로 정리했어요. 둘 중 하나를 골라주세요.",
      reflections: [ { docId: "essay-distance", kind: "update", change: "도입 문단 두 가지 버전 추가" } ],
    },
  ],
  reading: [], ideas: [],
};

// Fallback generic AI replies (cycled) when no trigger matches in a space
const GENERIC_SPACE_REPLIES = [
  { reply: "메모만 해두었어요. 새 문서로 만들 만큼은 아니라고 판단했습니다.", reflections: [] },
  { reply: "이 부분은 잠시 흘려보낼게요. 정리할 게 분명해지면 다시 짚을게요.", reflections: [] },
];

// Generic default-chat AI replies
const GENERIC_DEFAULT_REPLIES = [
  "흠, 좀 더 들려줄래요?",
  "기록해둘 만한 흐름인 것 같진 않아요. 그냥 흘려보낼게요.",
  "정리할 만하면 알려드릴게요. 일단 계속 적어보세요.",
];

// Convert legacy block-body to markdown string
function blocksToMd(body) {
  if (!body || !body.length) return "";
  return body.map(b => {
    if (b.type === "h1") return `# ${b.text || ""}`;
    if (b.type === "h2") return `## ${b.text || ""}`;
    if (b.type === "h3") return `### ${b.text || ""}`;
    if (b.type === "p")  return b.text || "";
    if (b.type === "ul") return (b.items || []).map(t => `- ${t}`).join("\n");
    if (b.type === "ol") return (b.items || []).map((t,i) => `${i+1}. ${t}`).join("\n");
    if (b.type === "callout") return `> ${b.text || ""}`;
    if (b.type === "fresh")   return `> ✻ ${b.text || ""}`;
    return b.text || "";
  }).join("\n\n");
}

function docMarkdown(doc) {
  if (!doc) return "";
  if (typeof doc.markdown === "string") return doc.markdown;
  return blocksToMd(doc.body || []);
}

Object.assign(window, {
  SPACES_INIT, DEFAULT_CHAT_INIT, DOCS_INIT, SESSIONS_INIT, HISTORY_INIT,
  SCRIPTS, GENERIC_SPACE_REPLIES, GENERIC_DEFAULT_REPLIES, PALETTE_OPTIONS,
  blocksToMd, docMarkdown,
});
