/* ============================================================
 * paper.jsx — PaperStrip component + presets
 * ============================================================ */

// === Paper color/texture presets (curated, refined) ===
const PAPER_COLORS = [
  { id: "cream",     name: "宣纸",  bg: "#f3ead4", ink: "#1a1612" },
  { id: "snow",      name: "雪白",  bg: "#f8f4ea", ink: "#1a1612" },
  { id: "rice",      name: "米黄",  bg: "#eadaa6", ink: "#1a1612" },
  { id: "kraft",     name: "牛皮",  bg: "#c9a878", ink: "#2a1c10" },
  { id: "dan",       name: "丹朱",  bg: "#c4453a", ink: "#1a1612" },
  { id: "vermilion", name: "正红",  bg: "#a8261b", ink: "#f2dd9a" },
  { id: "ochre",     name: "赭石",  bg: "#c97e3a", ink: "#1a1612" },
  { id: "saffron",   name: "藤黄",  bg: "#e8a93a", ink: "#1a1612" },
  { id: "celadon",   name: "青瓷",  bg: "#a8c2b3", ink: "#1a1612" },
  { id: "jade",      name: "石绿",  bg: "#7fa089", ink: "#1a1612" },
  { id: "indigo",    name: "靛青",  bg: "#9fb6c9", ink: "#1a1612" },
  { id: "twilight",  name: "天青",  bg: "#7f9bb2", ink: "#1a1612" },
  { id: "plum",      name: "胭脂",  bg: "#e9b6b1", ink: "#1a1612" },
  { id: "lilac",     name: "紫藤",  bg: "#b8a4c4", ink: "#1a1612" },
  { id: "sand",      name: "枯叶",  bg: "#a89172", ink: "#2a1c10" },
  { id: "moss",      name: "苔色",  bg: "#8a8a48", ink: "#1a1612" },
  { id: "ink",       name: "墨色",  bg: "#2a2520", ink: "#d4b56a" },
  { id: "gold",      name: "金粉",  bg: "#caa55a", ink: "#1a1612" },
];

// === Paper textures (overlay patterns) ===
const PAPER_TEXTURES = [
  { id: "plain",    name: "素",   svg: null },
  { id: "cloud",    name: "祥云", svg: "cloud" },
  { id: "gold",     name: "洒金", svg: "gold-fleck" },
  { id: "wave",     name: "水波", svg: "wave" },
  { id: "kikko",    name: "龟甲", svg: "kikko" },
  { id: "bamboo",   name: "竹叶", svg: "bamboo" },
  { id: "blossom",  name: "梅花", svg: "blossom" },
  { id: "fibers",   name: "纸纹", svg: "fibers" },
];

// === Fonts (calligraphy styles) ===
const FONTS = [
  { id: "kai",     name: "楷书", family: '"Noto Serif SC", serif',     weight: 600 },
  { id: "song",    name: "宋体", family: '"Noto Serif SC", serif',     weight: 700 },
  { id: "xing",    name: "行书", family: '"Ma Shan Zheng", cursive',   weight: 400 },
  { id: "cao",     name: "草书", family: '"Long Cang", cursive',       weight: 400 },
  { id: "caoZhi",  name: "狂草", family: '"Zhi Mang Xing", cursive',   weight: 400 },
  { id: "li",      name: "隶书", family: '"ZCOOL XiaoWei", serif',     weight: 400 },
  { id: "zhuan",   name: "篆书", family: '"ZCOOL QingKe HuangYou", serif', weight: 400 },
  { id: "shou",    name: "瘦金", family: '"ZCOOL XiaoWei", serif',     weight: 300, letterSpacing: "-0.02em" },
  { id: "maocao",  name: "毛草", family: '"Liu Jian Mao Cao", cursive', weight: 400 },
];

// === Shapes ===
// Each shape returns {aspectRatio, clipPath, isRound, defaultVertical}
const SHAPES = {
  "rect-v":   { name: "竖长条", ar: 0.28, defaultVertical: true,  clip: null },
  "rect-h":   { name: "横长条", ar: 3.6,  defaultVertical: false, clip: null },
  "square":   { name: "方胜",   ar: 1,    defaultVertical: false, clip: null },
  "diamond":  { name: "菱形",   ar: 1,    defaultVertical: false, clip: "polygon(50% 0, 100% 50%, 50% 100%, 0 50%)" },
  "circle":   { name: "圆福",   ar: 1,    defaultVertical: false, clip: "circle(50% at 50% 50%)" },
  "coin":     { name: "铜钱",   ar: 1,    defaultVertical: false, clip: "circle(50% at 50% 50%)", innerHole: true },
  "gourd":    { name: "葫芦",   ar: 0.66, defaultVertical: true,  clip: "path('M50 5 C30 5, 28 20, 32 32 C36 42, 22 48, 22 65 C22 85, 78 85, 78 65 C78 48, 64 42, 68 32 C72 20, 70 5, 50 5 Z')", clipSvgViewBox: "0 0 100 100" },
  "flower":   { name: "花瓣",   ar: 1,    defaultVertical: false, clip: "flower" },
  "pouch":    { name: "福袋",   ar: 0.85, defaultVertical: false, clip: "pouch" },
  "tall":     { name: "细长条", ar: 0.18, defaultVertical: true,  clip: null },
};

// Patterns are inline SVG data URLs
function makePatternUrl(kind, color = "#000", opacity = 0.4) {
  const c = encodeURIComponent(color);
  const a = opacity;
  let svg = "";
  switch (kind) {
    case "cloud":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'>
        <g fill='none' stroke='${color}' stroke-width='0.6' opacity='${a}'>
          <path d='M10 20 Q15 15, 22 18 T35 18 Q40 22, 35 26 T22 26 Q12 26, 10 20 Z'/>
          <path d='M50 50 Q55 45, 62 48 T75 48 Q80 52, 75 56 T62 56 Q52 56, 50 50 Z'/>
          <path d='M5 60 Q10 56, 16 58 T26 58'/>
          <path d='M45 10 Q50 7, 56 9 T66 9'/>
        </g>
      </svg>`;
      break;
    case "wave":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='60' height='30' viewBox='0 0 60 30'>
        <g fill='none' stroke='${color}' stroke-width='0.5' opacity='${a}'>
          <path d='M0 15 Q15 5, 30 15 T60 15'/>
          <path d='M0 22 Q15 12, 30 22 T60 22'/>
          <path d='M0 8 Q15 -2, 30 8 T60 8'/>
        </g>
      </svg>`;
      break;
    case "kikko":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='34' height='30' viewBox='0 0 34 30'>
        <g fill='none' stroke='${color}' stroke-width='0.5' opacity='${a}'>
          <polygon points='17,2 31,10 31,20 17,28 3,20 3,10'/>
          <polygon points='0,18 3,20 3,25' />
          <polygon points='34,18 31,20 31,25' />
        </g>
      </svg>`;
      break;
    case "bamboo":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'>
        <g fill='${color}' opacity='${a * 0.6}'>
          <path d='M20 10 Q25 25, 22 40 Q30 35, 38 42 Q32 28, 35 12 Q28 18, 20 10 Z'/>
          <path d='M55 55 Q60 70, 57 80 Q68 75, 74 82 Q68 68, 70 52 Q62 60, 55 55 Z'/>
        </g>
      </svg>`;
      break;
    case "blossom":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='70' height='70' viewBox='0 0 70 70'>
        <g fill='${color}' opacity='${a * 0.5}'>
          <g transform='translate(20 20)'>
            <circle cx='0' cy='-6' r='3'/>
            <circle cx='5.7' cy='-1.8' r='3'/>
            <circle cx='3.5' cy='4.8' r='3'/>
            <circle cx='-3.5' cy='4.8' r='3'/>
            <circle cx='-5.7' cy='-1.8' r='3'/>
            <circle cx='0' cy='0' r='1.5' fill='${color}'/>
          </g>
          <g transform='translate(50 45)'>
            <circle cx='0' cy='-5' r='2.5'/>
            <circle cx='4.8' cy='-1.5' r='2.5'/>
            <circle cx='3' cy='4' r='2.5'/>
            <circle cx='-3' cy='4' r='2.5'/>
            <circle cx='-4.8' cy='-1.5' r='2.5'/>
          </g>
        </g>
      </svg>`;
      break;
    case "fibers":
      svg = `<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'>
        <g stroke='${color}' stroke-width='0.3' opacity='${a * 0.5}' fill='none'>
          <path d='M0 30 Q50 28, 100 32 T200 30'/>
          <path d='M0 70 Q60 73, 120 70 T200 72'/>
          <path d='M0 110 Q40 108, 80 112 T200 110'/>
          <path d='M0 160 Q70 158, 140 162 T200 160'/>
          <path d='M20 0 Q22 50, 18 100 T22 200'/>
          <path d='M120 0 Q118 60, 122 130 T120 200'/>
        </g>
      </svg>`;
      break;
    case "gold-fleck":
      // gold flecks rendered separately, handled by gold-fleck layer
      return null;
    default:
      return null;
  }
  return `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}")`;
}

function makeGoldFleckSvg(seed = 0, density = 30) {
  // Deterministic random based on seed
  let s = seed * 9301 + 49297;
  const rand = () => { s = (s * 9301 + 49297) % 233280; return s / 233280; };
  const flecks = [];
  for (let i = 0; i < density; i++) {
    const x = rand() * 100;
    const y = rand() * 100;
    const r = 0.4 + rand() * 1.2;
    const op = 0.4 + rand() * 0.5;
    flecks.push(`<circle cx='${x.toFixed(2)}' cy='${y.toFixed(2)}' r='${r.toFixed(2)}' fill='%23d4b56a' opacity='${op.toFixed(2)}'/>`);
  }
  // larger flakes
  for (let i = 0; i < density / 3; i++) {
    const x = rand() * 100;
    const y = rand() * 100;
    const w = 1.5 + rand() * 2.5;
    const h = 0.8 + rand() * 1.2;
    const rot = rand() * 360;
    flecks.push(`<rect x='${x.toFixed(2)}' y='${y.toFixed(2)}' width='${w.toFixed(2)}' height='${h.toFixed(2)}' fill='%23c9a346' opacity='0.6' transform='rotate(${rot.toFixed(1)} ${x.toFixed(2)} ${y.toFixed(2)})'/>`);
  }
  return `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'>${flecks.join("")}</svg>`;
}

// === Shape custom SVG masks (for flower, pouch, etc.) ===
function ShapeMaskDef({ id, kind }) {
  if (kind === "flower") {
    // 4-petal flower
    return (
      <defs>
        <clipPath id={id} clipPathUnits="objectBoundingBox">
          <path d="M0.5,0.04 C0.62,0.04 0.7,0.14 0.66,0.28 C0.8,0.24 0.92,0.32 0.94,0.46 C0.96,0.6 0.86,0.7 0.72,0.66 C0.76,0.8 0.66,0.94 0.5,0.94 C0.34,0.94 0.24,0.8 0.28,0.66 C0.14,0.7 0.04,0.6 0.06,0.46 C0.08,0.32 0.2,0.24 0.34,0.28 C0.3,0.14 0.38,0.04 0.5,0.04 Z" />
        </clipPath>
      </defs>
    );
  }
  if (kind === "pouch") {
    return (
      <defs>
        <clipPath id={id} clipPathUnits="objectBoundingBox">
          <path d="M0.32,0.08 L0.68,0.08 L0.64,0.18 C0.86,0.24 0.96,0.42 0.96,0.62 C0.96,0.84 0.78,0.96 0.5,0.96 C0.22,0.96 0.04,0.84 0.04,0.62 C0.04,0.42 0.14,0.24 0.36,0.18 Z" />
        </clipPath>
      </defs>
    );
  }
  if (kind === "gourd") {
    return (
      <defs>
        <clipPath id={id} clipPathUnits="objectBoundingBox">
          <path d="M0.5,0.04 C0.3,0.04 0.28,0.18 0.34,0.3 C0.38,0.38 0.22,0.46 0.22,0.62 C0.22,0.84 0.78,0.84 0.78,0.62 C0.78,0.46 0.62,0.38 0.66,0.3 C0.72,0.18 0.7,0.04 0.5,0.04 Z" />
        </clipPath>
      </defs>
    );
  }
  return null;
}

// === PaperStrip component ===
function PaperStrip({
  text = "未来可期",
  shape = "rect-v",
  paperId = "cream",
  textureId = "plain",
  fontId = "xing",
  fontScale = 1,
  textColor = null,         // overrides default ink
  paperColor = null,        // overrides default bg
  showSeal = true,
  sealText = "福",
  sealPosition = "bottom",  // top|bottom|tl|br
  sealRound = false,
  showBorder = false,
  borderStyle = "single",   // single|double
  showGoldFleck = false,
  vertical = null,          // null = use shape default
  width = 100,              // % or px depending on parent
  fillSize = false,
  // collage-related
  rotate = 0,
  shadow = "soft",          // soft|hard|none
  paperWear = false,
  seed = 1,
}) {
  const paperPreset = PAPER_COLORS.find(p => p.id === paperId) || PAPER_COLORS[0];
  const shapeDef = SHAPES[shape] || SHAPES["rect-v"];
  const font = FONTS.find(f => f.id === fontId) || FONTS[0];
  const isVertical = vertical !== null ? vertical : shapeDef.defaultVertical;

  const bg = paperColor || paperPreset.bg;
  const ink = textColor || paperPreset.ink;

  const aspectRatio = shapeDef.ar;
  const clipMaskId = `mask-${shape}-${seed}`;
  const needsSvgClip = shapeDef.clip === "flower" || shapeDef.clip === "pouch" || shapeDef.clip === "gourd";

  const clipPath = needsSvgClip
    ? `url(#${clipMaskId})`
    : (shapeDef.clip || undefined);

  // Font size — strip-text is its own size container; chars fill it
  const chars = Array.from(text).filter(c => c.trim());
  const charCount = chars.length || 1;
  let fontSize;
  if (isVertical) {
    fontSize = `calc(min(92cqw, ${(92 / charCount).toFixed(1)}cqh) * ${fontScale})`;
  } else {
    fontSize = `calc(min(92cqh, ${(92 / charCount).toFixed(1)}cqw) * ${fontScale})`;
  }

  const patternUrl = makePatternUrl(textureId === "gold" ? null : textureId, ink, 0.5);

  // shadow style
  let boxShadow;
  if (shadow === "soft") boxShadow = "0 6px 16px -8px rgba(0,0,0,0.35), 0 2px 4px -2px rgba(0,0,0,0.2)";
  else if (shadow === "hard") boxShadow = "0 10px 0 -6px rgba(0,0,0,0.15), 0 14px 30px -10px rgba(0,0,0,0.4)";
  else boxShadow = "none";

  const sealCharFinal = (sealText && sealText.length > 0) ? sealText[0] : "";

  // Seal layout mode
  const sealIsCorner = sealPosition === "tl" || sealPosition === "br";
  const sealCornerStyle = {
    tl:  { top: "4%", left: "4%" },
    br:  { bottom: "4%", right: "4%" },
  }[sealPosition];

  // Content container direction. Items are in JSX order: text, then seal.
  // We want: when sealPosition=top, seal first (at top). For 'col', seal needs to be first in DOM.
  // Simpler: render JSX order [text, seal], then for top use column-reverse / row-reverse.
  let contentClass = "strip-content ";
  if (!sealIsCorner && showSeal && sealCharFinal) {
    if (isVertical) {
      contentClass += sealPosition === "top" ? "rev" : "col";
    } else {
      contentClass += sealPosition === "top" ? "rev-row" : "row";
    }
  } else {
    contentClass += isVertical ? "col" : "row";
  }

  // Glyph styling for vertical: each char is one cell
  const glyphStyle = {
    fontFamily: font.family,
    fontWeight: font.weight,
    color: ink,
    fontSize: fontSize,
    letterSpacing: font.letterSpacing || (isVertical ? "0" : "0.04em"),
    lineHeight: 1,
  };

  // Background composition
  const baseBg = bg;
  // subtle inner shading
  const innerShade = `radial-gradient(120% 80% at 50% 0%, rgba(255,255,255,0.18), transparent 60%), radial-gradient(120% 80% at 50% 100%, rgba(0,0,0,0.1), transparent 60%)`;

  return (
    <div
      className="strip"
      style={{
        width: fillSize ? "100%" : `${width}px`,
        ...(fillSize ? { height: "100%" } : { aspectRatio: aspectRatio }),
        transform: rotate ? `rotate(${rotate}deg)` : undefined,
        filter: paperWear ? "contrast(1.02) saturate(0.96)" : undefined,
      }}
    >
      <div
        className="strip-inner"
        style={{
          clipPath: clipPath,
          WebkitClipPath: clipPath,
          boxShadow,
          borderRadius: shape === "rect-v" || shape === "rect-h" || shape === "square" || shape === "tall" ? "2px" : 0,
        }}
      >
        {needsSvgClip && (
          <svg width="0" height="0" style={{ position: "absolute" }}>
            <ShapeMaskDef id={clipMaskId} kind={shapeDef.clip} />
          </svg>
        )}

        {/* paper base */}
        <div
          className="strip-paper"
          style={{
            background: `${innerShade}, ${baseBg}`,
          }}
        />

        {/* pattern */}
        {patternUrl && (
          <div
            className="strip-pattern"
            style={{
              backgroundImage: patternUrl,
              backgroundSize: textureId === "fibers" ? "100% 100%" : undefined,
              opacity: textureId === "fibers" ? 0.5 : 0.55,
            }}
          />
        )}

        {/* gold fleck (texture or explicit) */}
        {(textureId === "gold" || showGoldFleck) && (
          <div
            className="gold-fleck"
            style={{
              backgroundImage: `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(makeGoldFleckSvg(seed, 36))}")`,
              backgroundSize: "100% 100%",
              opacity: 0.7,
            }}
          />
        )}

        {/* border */}
        {showBorder && (
          <div
            className={`strip-border ${borderStyle === "double" ? "double" : ""}`}
            style={{ color: ink, borderRadius: "inherit" }}
          />
        )}

        {/* Coin hole */}
        {shape === "coin" && (
          <div style={{
            position: "absolute",
            inset: 0,
            zIndex: 6,
            background: "radial-gradient(transparent 18%, #00000022 18.5%, transparent 19%)",
            pointerEvents: "none",
          }} />
        )}

        {/* content (text + inline seal) */}
        <div className={contentClass}>
          <div className={`strip-text ${isVertical ? "vertical" : ""}`}>
            <div className="glyphs" style={glyphStyle}>
              {chars.map((c, i) => (
                <span key={i} className="ch">{c}</span>
              ))}
            </div>
          </div>
          {showSeal && sealCharFinal && !sealIsCorner && (
            <div className={`seal-row ${isVertical ? "vertical" : "horizontal"}`}>
              <div
                className={`seal-mark ${sealRound ? "round" : ""} ${isVertical ? "inline-h" : "inline-v"}`}
                style={{
                  background: paperId === "dan" || paperId === "vermilion" ? "#7c1f17" : "#c4453a",
                  color: "#f8e8c4",
                  ...(isVertical ? { width: "70%" } : { height: "70%" }),
                }}
              >
                <span>{sealCharFinal}</span>
              </div>
            </div>
          )}
        </div>

        {/* corner seal (absolute) */}
        {showSeal && sealCharFinal && sealIsCorner && (
          <div
            className={`seal-mark corner ${sealRound ? "round" : ""}`}
            style={{
              ...sealCornerStyle,
              background: paperId === "dan" || paperId === "vermilion" ? "#7c1f17" : "#c4453a",
              color: "#f8e8c4",
            }}
          >
            <span>{sealCharFinal}</span>
          </div>
        )}
      </div>
    </div>
  );
}

// === Reusable shape icon (for shape picker) ===
function ShapeIcon({ kind }) {
  const s = SHAPES[kind] || SHAPES["rect-v"];
  const fill = "var(--ink-soft)";
  const w = 60;
  const h = 60;
  // Render a small representation
  if (kind === "rect-v") return (<svg viewBox="0 0 60 60"><rect x="22" y="6" width="16" height="48" fill={fill} rx="1"/></svg>);
  if (kind === "tall")   return (<svg viewBox="0 0 60 60"><rect x="26" y="4" width="8" height="52" fill={fill} rx="1"/></svg>);
  if (kind === "rect-h") return (<svg viewBox="0 0 60 60"><rect x="6" y="24" width="48" height="14" fill={fill} rx="1"/></svg>);
  if (kind === "square") return (<svg viewBox="0 0 60 60"><rect x="12" y="12" width="36" height="36" fill={fill} rx="1"/></svg>);
  if (kind === "diamond")return (<svg viewBox="0 0 60 60"><polygon points="30,6 54,30 30,54 6,30" fill={fill}/></svg>);
  if (kind === "circle") return (<svg viewBox="0 0 60 60"><circle cx="30" cy="30" r="22" fill={fill}/></svg>);
  if (kind === "coin")   return (<svg viewBox="0 0 60 60"><circle cx="30" cy="30" r="22" fill={fill}/><rect x="25" y="25" width="10" height="10" fill="var(--paper)"/></svg>);
  if (kind === "gourd")  return (<svg viewBox="0 0 60 60"><path d="M30 6 C20 6, 18 16, 22 22 C25 28, 16 32, 16 42 C16 54, 44 54, 44 42 C44 32, 35 28, 38 22 C42 16, 40 6, 30 6 Z" fill={fill}/></svg>);
  if (kind === "flower") return (<svg viewBox="0 0 60 60"><path d="M30,4 C36,4 41,9 38,17 C46,15 53,20 54,28 C55,36 49,42 41,40 C43,48 38,55 30,55 C22,55 17,48 19,40 C11,42 5,36 6,28 C7,20 14,15 22,17 C19,9 24,4 30,4 Z" fill={fill}/></svg>);
  if (kind === "pouch")  return (<svg viewBox="0 0 60 60"><path d="M20 10 L40 10 L37 16 C50 20 56 32 56 42 C56 53 45 56 30 56 C15 56 4 53 4 42 C4 32 10 20 23 16 Z" fill={fill}/></svg>);
  return <svg viewBox="0 0 60 60"><rect x="22" y="6" width="16" height="48" fill={fill}/></svg>;
}

// expose
Object.assign(window, { PaperStrip, ShapeIcon, PAPER_COLORS, PAPER_TEXTURES, FONTS, SHAPES });
