// ===========================================================
// 앱 스킨 — 꾸미기 탭에서 한 번에 적용되는 프리셋 묶음
// (배경·헤더·포인트·할 일 행 스타일 등)
//
// 아키텍처: 본 프로그램(기본·카와이)과 스킨 껍데기 분리.
// - SKIN_DEFAULT_ID: data-skin 없음 — 기본 UI·동작은 여기만 유지
// - notion(흑백) / excel(스프레드 시트): html[data-skin] + excel*Class() 헬퍼로만 스타일 주입
// - excel*Class()는 isExcelSkin() 일 때만 class 반환 (그 외 "")
// ===========================================================

const SKIN_DEFAULT_ID = "default";
const OFFICE_SKINS = new Set(["notion", "excel"]);

/** 카와이 기본 스킨 — TWEAK_DEFAULTS 와 동기화 */
const PATCH_KAWAII = {
  appSkin: SKIN_DEFAULT_ID,
  bgType: "linear",
  bgAngle: 180,
  bgStops: [{ c: "#a9cdf5", p: 0 }, { c: "#ffffff", p: 100 }],
  bgShape: "none",
  chromeColor: "#a9cdf5",
  chromeGradient: true,
  tabAccent: "#ffc7d4",
  todoTapePalette: [
    "#ffeaf2", "#fffbd1", "#e9f8d8", "#fde0e5", "#dcf4e3",
    "#efe8f8", "#dfeaf9", "#fbf0d8", "#ffe9da", "#e3f3ff",
  ],
  todoTapePattern: "dots",
  todoTapePinColor: "#fff5b8",
  todoTapeBorderWidth: 0,
  todoTapeBorderColor: "var(--ink-soft)",
  todoTapeEdgeFade: true,
  todoTapePatternColor: "#ffffff",
  todoTapeGradFrom: "#fff5f8",
  todoTapeGradTo: "#ff9bb3",
};

/** 유료 스킨 PATCH — 공개 repo에 두지 않음. 비공개 저장소 manifest.patch + redeem 으로 배포. */

/** 꾸미기 UI용 — 무료만 동봉. 유료는 catalog + SkinRuntime 갤러리 */
const SKINS = [
  {
    id: SKIN_DEFAULT_ID,
    nameKey: "skin.default",
    descKey: "skin.defaultDesc",
    preview: ["#a9cdf5", "#ffc7d4", "#ffeaf2", "#ffffff"],
    patch: PATCH_KAWAII,
  },
];

function getActiveSkinId() {
  if (typeof document === "undefined") return SKIN_DEFAULT_ID;
  return document.documentElement.getAttribute("data-skin") || SKIN_DEFAULT_ID;
}

function getSkinById(id) {
  const rt = window.SkinRuntime;
  if (rt?.getGalleryEntries) {
    const g = rt.getGalleryEntries().find((s) => s.id === id);
    if (g) {
      const patch = rt.getPatch(id);
      return {
        id,
        nameKey: g.nameKey,
        descKey: g.descKey,
        preview: g.previewColors || ["#a9cdf5", "#ffffff"],
        patch: patch || PATCH_KAWAII,
        locked: g.locked && !g.unlocked,
      };
    }
  }
  return SKINS.find((s) => s.id === id) || SKINS[0];
}

function getSkinPatch(id) {
  const fromRt = window.SkinRuntime?.getPatch?.(id);
  if (fromRt) return { ...fromRt };
  return { ...(getSkinById(id).patch) };
}

function applySkinDom(id) {
  const skin = id || SKIN_DEFAULT_ID;
  if (typeof document === "undefined") return;
  const el = document.documentElement;
  const prev = el.getAttribute("data-skin") || SKIN_DEFAULT_ID;
  const next = skin === SKIN_DEFAULT_ID ? SKIN_DEFAULT_ID : skin;
  if (skin === SKIN_DEFAULT_ID) el.removeAttribute("data-skin");
  else el.setAttribute("data-skin", skin);
  if (prev !== next) {
    try {
      window.dispatchEvent(new CustomEvent("todoary:skin-dom", { detail: { from: prev, to: next } }));
    } catch (_) { /* ignore */ }
  }
}

function applySkinRuntime(patch) {
  if (typeof document === "undefined" || !patch) return;
  if (patch.tabAccent) {
    if (window.applyAccent) window.applyAccent(patch.tabAccent);
    else document.documentElement.style.setProperty("--hi", patch.tabAccent);
  }
  if (patch.chromeColor) {
    document.documentElement.style.setProperty("--chrome", patch.chromeColor);
  }
  applySkinDom(patch.appSkin || SKIN_DEFAULT_ID);
}

function isNotionSkin() {
  return getActiveSkinId() === "notion";
}

function isExcelSkin() {
  return getActiveSkinId() === "excel";
}

function isOfficeSkin() {
  return OFFICE_SKINS.has(getActiveSkinId());
}

/** 오피스 스킨 — 이모지 대신 기본 유니코드 기호 */
const SKIN_GLYPH = {
  play: "▶",
  pause: "‖",
  prev: "◀",
  next: "▶",
  vol0: "·",
  vol1: "··",
  vol2: "···",
  lock: "■",
  clap: "*",
  visible: "●",
  hidden: "○",
  pin: "■",
  save: "▽",
  folder: "□",
  memo: "□",
  clock: "○",
  bell: "!",
  gear: "⚙",
  tomato: "○",
  mail: "□",
  mailDone: "■",
  user: "○",
  cal: "□",
  list: "□",
  link: "↗",
  note: "□",
  schedule: "□",
  copy: "⧉",
  good: "+",
  bad: "−",
  ai: "*",
  expand: "▾",
  collapse: "▸",
  sparkle: "*",
  music: "·",
  empty: "—",
  drag: "⋮",
  draft: "✎",
  mailWrite: "□",
  mailLetter: "□",
};

/** 다이어리 인덱스 탭 — 오피스 스킨에서 스프라이트 대신 표시 */
const TAB_GLYPH = {
  todo: "≡",
  cal: "▦",
  memo: "□",
  mail: "□",
  room: "○",
  deco: "◇",
  settings: "⚙",
};

function skinTabGlyph(tabId) {
  if (!isOfficeSkin()) return null;
  return TAB_GLYPH[tabId] ?? "□";
}

function stripEmoji(text) {
  return String(text ?? "")
    .replace(/\p{Extended_Pictographic}/gu, "")
    .replace(/[\u{1F000}-\u{1FAFF}]/gu, "")
    .replace(/♫/g, "·")
    .replace(/♡/g, "")
    .replace(/\s{2,}/g, " ")
    .trim();
}

function skinG(key, fallback) {
  if (!isOfficeSkin()) return fallback ?? "";
  const g = SKIN_GLYPH[key];
  if (g != null) return g;
  return stripEmoji(fallback ?? "");
}

function skinLabel(text) {
  if (!isOfficeSkin()) return text;
  return stripEmoji(text);
}

/** 작업방·프로필 상태 점 */
function roomStatusDotColor(status) {
  if (isNotionSkin()) {
    switch (status) {
      case "working": return "#191919";
      case "away": return "#787774";
      case "online": return "#b0b0ad";
      case "offline":
      case "paused":
      case "idle":
      default: return "#d4d4d2";
    }
  }
  if (isExcelSkin()) {
    switch (status) {
      case "working": return "#217346";
      case "away": return "#a6a6a6";
      case "online": return "#7f7f7f";
      case "offline":
      case "paused":
      case "idle":
      default: return "#d4d4d4";
    }
  }
  return null;
}

/**
 * 스프레드 시트 스킨 전용 className — 활성 스킨이 excel 일 때만 반환.
 * 기본(카와이)·흑백에는 빈 문자열만 반환 (스킨 껍데기와 본체 분리).
 */
function excelSheetClass(extra) {
  if (!isExcelSkin()) return "";
  return ["excel-sheet-view", extra].filter(Boolean).join(" ");
}
function excelPanelClass(extra) {
  if (!isExcelSkin()) return "";
  return ["excel-panel", extra].filter(Boolean).join(" ");
}
function excelRibbonClass(extra) {
  if (!isExcelSkin()) return "";
  return ["excel-ribbon", extra].filter(Boolean).join(" ");
}
function excelRowClass(extra) {
  if (!isExcelSkin()) return "";
  return ["excel-table-row", extra].filter(Boolean).join(" ");
}
function excelHeaderClass(extra) {
  if (!isExcelSkin()) return "";
  return ["excel-dock-header", extra].filter(Boolean).join(" ");
}

window.SKIN_DEFAULT_ID = SKIN_DEFAULT_ID;
window.PATCH_KAWAII = PATCH_KAWAII;
window.SKINS = SKINS;
window.getSkinById = getSkinById;
window.getSkinPatch = getSkinPatch;
window.getActiveSkinId = getActiveSkinId;
window.applySkinDom = applySkinDom;
window.applySkinRuntime = applySkinRuntime;
window.isNotionSkin = isNotionSkin;
window.isExcelSkin = isExcelSkin;
window.isOfficeSkin = isOfficeSkin;
window.skinG = skinG;
window.skinTabGlyph = skinTabGlyph;
window.skinLabel = skinLabel;
window.stripEmoji = stripEmoji;
window.roomStatusDotColor = roomStatusDotColor;
window.excelSheetClass = excelSheetClass;
window.excelPanelClass = excelPanelClass;
window.excelRibbonClass = excelRibbonClass;
window.excelRowClass = excelRowClass;
window.excelHeaderClass = excelHeaderClass;
