// Sample chart data — Rubie's chart in production normalized shape
// per technical handoff §7. After the Worker /get-chart response is parsed,
// planets/houseCusps look like this. Components should read these field names
// and derive display values via lookups.jsx (PLANET_ZH, SIGN_ZH, etc.).

// ─── Normalized planet shape (handoff §7) ──────────────────────────────────
//   { name, sign, signAbbr, house, deg, absLon, retro }
// ─── Normalized house cusp shape ───────────────────────────────────────────
//   { house, sign, signAbbr, deg, absLon }

const SAMPLE_CHART = {
  // inputData echo (handoff §6)
  inputData: {
    name: 'Rubie',
    email: 'rubie@example.com',
    year: 1985, month: 10, day: 12,
    hour: 14, minute: 35,
    city: '香港 · Hong Kong',
    lat: 22.3193, lng: 114.1694,
    tz_str: 'Asia/Hong_Kong',
  },

  // Convenience aliases for the design code (mirrors what result.astro builds)
  name: 'Rubie',
  birth: {
    date: '1985-10-12',
    time: '14:35',
    location: '香港 · Hong Kong',
    lat: 22.3193, lon: 114.1694, tz: '+08:00',
  },

  // Ascendant absolute longitude — anchors the wheel
  ascLon: 84.83,

  // Planets — normalized shape
  planets: [
    { name:'Ascendant',  sign:'Gemini',      signAbbr:'Gem', house:1,  deg:24.83, absLon: 84.83, retro:false },
    { name:'Sun',        sign:'Libra',       signAbbr:'Lib', house:5,  deg:19.38, absLon:199.38, retro:false },
    { name:'Moon',       sign:'Cancer',      signAbbr:'Can', house:1,  deg: 7.18, absLon: 97.18, retro:false },
    { name:'Mercury',    sign:'Scorpio',     signAbbr:'Sco', house:5,  deg: 2.78, absLon:212.78, retro:false },
    { name:'Venus',      sign:'Virgo',       signAbbr:'Vir', house:4,  deg:28.25, absLon:178.25, retro:false },
    { name:'Mars',       sign:'Capricorn',   signAbbr:'Cap', house:7,  deg:11.53, absLon:281.53, retro:false },
    { name:'Jupiter',    sign:'Aquarius',    signAbbr:'Aqu', house:8,  deg:19.13, absLon:319.13, retro:false },
    { name:'Saturn',     sign:'Scorpio',     signAbbr:'Sco', house:6,  deg:21.73, absLon:231.73, retro:false },
    { name:'Uranus',     sign:'Sagittarius', signAbbr:'Sag', house:6,  deg:14.37, absLon:254.37, retro:true  },
    { name:'Neptune',    sign:'Capricorn',   signAbbr:'Cap', house:7,  deg: 2.15, absLon:272.15, retro:true  },
    { name:'Pluto',      sign:'Scorpio',     signAbbr:'Sco', house:5,  deg: 3.27, absLon:213.27, retro:false },
    { name:'Chiron',     sign:'Gemini',      signAbbr:'Gem', house:12, deg:11.40, absLon: 71.40, retro:true  },
    { name:'North Node', sign:'Taurus',      signAbbr:'Tau', house:11, deg: 5.85, absLon: 35.85, retro:false },
    { name:'South Node', sign:'Scorpio',     signAbbr:'Sco', house:5,  deg: 5.85, absLon:215.85, retro:false },
  ],

  // Placidus house cusps — unequal except for the 4 angles (AC/IC/DC/MC)
  houseCusps: [
    { house:1,  sign:'Gemini',      signAbbr:'Gem', deg:24.83, absLon: 84.83 },
    { house:2,  sign:'Cancer',      signAbbr:'Can', deg:26.00, absLon:116.00 },
    { house:3,  sign:'Leo',         signAbbr:'Leo', deg:23.00, absLon:143.00 },
    { house:4,  sign:'Virgo',       signAbbr:'Vir', deg:18.00, absLon:168.00 },
    { house:5,  sign:'Libra',       signAbbr:'Lib', deg:16.00, absLon:196.00 },
    { house:6,  sign:'Scorpio',     signAbbr:'Sco', deg:20.00, absLon:230.00 },
    { house:7,  sign:'Sagittarius', signAbbr:'Sag', deg:24.83, absLon:264.83 },
    { house:8,  sign:'Capricorn',   signAbbr:'Cap', deg:26.00, absLon:296.00 },
    { house:9,  sign:'Aquarius',    signAbbr:'Aqu', deg:23.00, absLon:323.00 },
    { house:10, sign:'Pisces',      signAbbr:'Pis', deg:18.00, absLon:348.00 },
    { house:11, sign:'Aries',       signAbbr:'Ari', deg:16.00, absLon: 16.00 },
    { house:12, sign:'Taurus',      signAbbr:'Tau', deg:20.00, absLon: 50.00 },
  ],
};

// ─── Display helpers ───────────────────────────────────────────────────────
// formatDeg(p) → "19°23′" or "14°22′℞"
// These mirror what result.astro does in its rendering helpers.

function formatDeg(p){
  const whole = Math.floor(p.deg);
  const mins  = Math.round((p.deg - whole) * 60);
  return `${String(whole).padStart(2,'0')}°${String(mins).padStart(2,'0')}′${p.retro ? '℞' : ''}`;
}

// planetView — derive display fields for a normalized planet object using
// the lookup tables in lookups.jsx. Components iterate big3/others which
// have been pre-decorated via planetView() and then enriched with interp text.
function planetView(p){
  const sign = p.sign;
  const PZ = window.PLANET_ZH || {}, SZ = window.SIGN_ZH || {};
  const PG = window.PLANET_GLYPH || {}, PC = window.PLANET_COLOR || {};
  const PR = window.PLANET_ROLE || {};
  return {
    // raw normalized fields (production shape)
    name: p.name, sign, signAbbr: p.signAbbr, house: p.house,
    deg: p.deg, absLon: p.absLon, retro: p.retro,
    // derived display fields (via lookups)
    key:     p.name.toLowerCase().replace(/\s+/g, '-'),
    cn:      PZ[p.name] || p.name,
    en:      p.name === 'Ascendant' ? 'Rising' : p.name,
    signCn:  (SZ[sign] || sign).replace(/座$/, ''),  // "天秤" w/o 座 suffix
    signZh:  SZ[sign] || sign,                       // "天秤座" full
    signEn:  sign,
    glyph:   PG[p.name] || '?',
    color:   PC[p.name] || '#8B93D4',
    role:    PR[p.name] || '',
    degree:  formatDeg(p),
    degLabel:formatDeg(p),
  };
}

// ─── Interpretation lookup ─────────────────────────────────────────────────
// Production loads /interpretations.json at runtime via fetch (handoff §10).
// In this preview we do the same — app.jsx awaits the fetch before rendering.
// Access via accessors in lookups.jsx: getPlanetInSign(), getSignInHouse(),
// getElementStamp(), getModalityStamp(), getSoulSignatureBySign(),
// getSoulSignatureByDominance(), getQuadrant(), getStellium().

// ─── Chart ruler (個人守護星 / 守護小天使) ───────────────────────────────────
// Per CHART_RULER_IMPLEMENTATION_GUIDE: use the sign on the 1st-house cusp,
// traditional rulerships (Scorpio→Mars, Aquarius→Saturn, Pisces→Jupiter, …),
// then read the ruler planet's house. Text from chart_ruler_planets /
// chart_ruler_houses (prefers _child keys).
const RULER_BY_SIGN = {
  Aries:'Mars', Scorpio:'Mars', Taurus:'Venus', Libra:'Venus',
  Gemini:'Mercury', Virgo:'Mercury', Cancer:'Moon', Leo:'Sun',
  Sagittarius:'Jupiter', Pisces:'Jupiter', Capricorn:'Saturn', Aquarius:'Saturn',
};
// Portable: compute the chart-ruler view object from normalized planets + cusps.
function computeChartRuler(planets, cusps){
  const first = (cusps || []).find(h => h.house === 1);
  if (!first) return null;
  const ascSign = (window.SIGN_MAP?.[first.signAbbr]) || first.sign;
  const rulerName = RULER_BY_SIGN[ascSign];
  const rulerP = rulerName && (planets || []).find(p => p.name === rulerName);
  if (!rulerP) return null;
  const planetInterp = window.getChartRulerPlanet?.(rulerName);
  const houseInterp  = rulerP.house ? window.getChartRulerHouse?.(rulerP.house) : null;
  return {
    ...planetView(rulerP),
    ascSign,
    ascSignZh: (window.SIGN_ZH?.[ascSign] || ascSign),
    rulerText: planetInterp?.text || '',   // planet AS chart ruler
    houseText: houseInterp?.text || '',    // planet IN its house
  };
}
function buildChartRuler(){
  SAMPLE_CHART.chartRuler = computeChartRuler(SAMPLE_CHART.planets, SAMPLE_CHART.houseCusps);
}

// ─── $68 synthesis data — counts + status (computed from planets[]) ──────
// Text fields (.stamps, .soulType, .quadrant, .stelliums[].text) are filled
// in by buildDerivedChartData() once INTERPRETATIONS loads.
const SYNTHESIS = {
  elements:   { fire:1, earth:4, air:4, water:5 },   // out of 14
  modalities: { cardinal:5, fixed:6, mutable:3 },
  elementStatus:  { fire:'missing', earth:'normal', air:'normal', water:'dominant' },
  modalityStatus: { cardinal:'normal', fixed:'dominant', mutable:'normal' },

  // Hemisphere counts (production uses 4 hemispheres, not 2×2 quadrants).
  // Derived from planet house positions in buildDerivedChartData().
  hemispheres: { top:0, bottom:0, left:0, right:0 },
  dominantHemisphere: null,  // 'top'|'bottom'|'left'|'right'

  // Text fields filled by buildDerivedChartData():
  elementStamps:  {},   // { fire: stampObj|null, earth: ..., air: ..., water: ... }
  modalityStamps: {},   // { cardinal: ..., fixed: ..., mutable: ... }
  soulType:       null, // { name, symbol, text } | null
  hemisphereInterp: null, // { direction, title, text } | null

  stelliums: [
    { kind:'sign',  label:'天蠍',  labelEn:'Scorpio',
      planets:['Mercury','Saturn','Pluto','South Node'], text:'', title:'' },
    { kind:'house', label:'第 5 宮', labelEn:'House 5',
      planets:['Sun','Mercury','Pluto','South Node'], text:'', title:'' },
  ],
  signsInHouses: [],
};

// ─── Build derived chart data after INTERPRETATIONS loads ─────────────────
// Components reference SAMPLE_CHART.big3, SAMPLE_CHART.others, SYNTHESIS.* etc.
// This function rebuilds them with real interpretation text. Call from app.jsx
// AFTER fetch('/interpretations.json') resolves.
const _BIG3_SIGN_META = {
  Aries:       { headline:'勇敢直接，充滿行動', keywords:['勇氣','主動','熱情','冒險','開始'] },
  Taurus:      { headline:'穩定踏實，重視安全', keywords:['穩定','感官','耐性','安全','堅持'] },
  Gemini:      { headline:'好奇靈活，善於連結', keywords:['好奇','交流','學習','靈活','聯結'] },
  Cancer:      { headline:'情感細膩，重視歸屬', keywords:['照顧','家庭','安全感','感受','保護'] },
  Leo:         { headline:'自信溫暖，渴望發光', keywords:['自信','創造','表達','熱情','肯定'] },
  Virgo:       { headline:'細心觀察，追求秩序', keywords:['細心','秩序','服務','分析','練習'] },
  Libra:       { headline:'追求平衡，渴望和諧', keywords:['平衡','和諧','關係','美學','公平'] },
  Scorpio:     { headline:'感受深刻，內在強韌', keywords:['深度','信任','直覺','韌性','轉化'] },
  Sagittarius: { headline:'自由探索，熱愛成長', keywords:['探索','自由','信念','遠方','成長'] },
  Capricorn:   { headline:'踏實有責任，慢慢成長', keywords:['責任','耐力','目標','紀律','成熟'] },
  Aquarius:    { headline:'獨立特別，喜歡創新', keywords:['獨立','創新','朋友','未來','想法'] },
  Pisces:      { headline:'感受柔軟，想像豐富', keywords:['想像','同理','夢想','藝術','感受'] },
};
const _BIG3_SIGN_META_EN = {
  Aries:       { headline:'Brave & Direct, Ready to Act', keywords:['Courage','Initiative','Warmth','Adventure','Beginnings'] },
  Taurus:      { headline:'Steady & Grounded, Needs Security', keywords:['Steady','Senses','Patience','Security','Persistence'] },
  Gemini:      { headline:'Curious & Flexible, Loves Connection', keywords:['Curiosity','Communication','Learning','Flexible','Connection'] },
  Cancer:      { headline:'Sensitive & Caring, Needs Belonging', keywords:['Care','Family','Security','Feeling','Protective'] },
  Leo:         { headline:'Warm & Confident, Ready to Shine', keywords:['Confidence','Creativity','Expression','Warmth','Recognition'] },
  Virgo:       { headline:'Observant & Careful, Seeks Order', keywords:['Careful','Order','Service','Analysis','Practice'] },
  Libra:       { headline:'Seeks Balance, Longs for Harmony', keywords:['Balance','Harmony','Relationships','Aesthetics','Fairness'] },
  Scorpio:     { headline:'Deeply Feeling, Quietly Resilient', keywords:['Depth','Trust','Intuition','Resilience','Transformation'] },
  Sagittarius: { headline:'Free-Spirited, Loves to Explore', keywords:['Exploration','Freedom','Belief','Faraway','Growth'] },
  Capricorn:   { headline:'Responsible & Steady, Grows with Time', keywords:['Responsibility','Endurance','Goals','Discipline','Maturity'] },
  Aquarius:    { headline:'Independent & Original, Loves New Ideas', keywords:['Independent','Original','Friends','Future','Ideas'] },
  Pisces:      { headline:'Tender & Imaginative, Deeply Feeling', keywords:['Imagination','Empathy','Dreams','Art','Feeling'] },
};
function _big3MetaFor(p){
  const sign = window.CC?.SIGN_MAP?.[p.sign] || p.sign;
  const map = window.klang?.() === 'en' ? _BIG3_SIGN_META_EN : _BIG3_SIGN_META;
  return map[sign] || { headline:'', keywords:[] };
}
window.kidBig3MetaFor = _big3MetaFor;
const _MODE_SHORT = { cardinal:'card', fixed:'fix', mutable:'mut' };
function _statusShort(s){ return s === 'dominant' ? 'dom' : s === 'missing' ? 'miss' : null; }

function buildDerivedChartData(){
  // 1) Big 3 — interp text from real lookups; Ascendant uses house_1_<sign>.
  SAMPLE_CHART.big3 = ['Sun','Moon','Ascendant']
    .map(n => SAMPLE_CHART.planets.find(p => p.name === n))
    .filter(Boolean)
    .map(p => {
      const view = planetView(p);
      const interp = p.name === 'Ascendant'
        ? window.getAscendantInSign(p.sign)
        : window.getPlanetInSign(p.name, p.sign);
      return {
        ...view,
        headline: _big3MetaFor(p).headline,
        keywords: _big3MetaFor(p).keywords,
        summary:  interp?.text || '',
      };
    });

  // 2) Other planets — interp text from sun_libra-style key
  SAMPLE_CHART.others = SAMPLE_CHART.planets
    .filter(p => !['Sun','Moon','Ascendant'].includes(p.name))
    .map(p => ({
      ...planetView(p),
      summary: window.getPlanetInSign(p.name, p.sign)?.text || '',
    }));

  // 3) Signs in houses — derived from houseCusps + signs_in_houses
  SYNTHESIS.signsInHouses = SAMPLE_CHART.houseCusps.map(c => {
    const interp = window.getSignInHouse(c.house, c.sign);
    return {
      house:  c.house,
      sign:   (window.SIGN_ZH?.[c.sign] || c.sign).replace(/座$/, ''),
      signEn: c.sign,
      interp: interp?.text || '',
    };
  });

  // 4) Element + modality stamps (only for 'dominant' / 'missing')
  for (const elem of ['fire','earth','air','water']) {
    const st = _statusShort(SYNTHESIS.elementStatus[elem]);
    SYNTHESIS.elementStamps[elem] = st ? window.getElementStamp(elem, st) : null;
  }
  for (const mode of ['cardinal','fixed','mutable']) {
    const st = _statusShort(SYNTHESIS.modalityStatus[mode]);
    const short = _MODE_SHORT[mode];
    SYNTHESIS.modalityStamps[mode] = st ? window.getModalityStamp(short, st) : null;
  }

  // 5) Soul Signature — dominant element × dominant modality maps to a sign
  const dEl   = Object.entries(SYNTHESIS.elementStatus).find(([,s]) => s === 'dominant')?.[0];
  const dMode = Object.entries(SYNTHESIS.modalityStatus).find(([,s]) => s === 'dominant')?.[0];
  if (dEl && dMode) {
    SYNTHESIS.soulType = window.getSoulSignatureByDominance(dEl, _MODE_SHORT[dMode]);
  }

  // 6) Hemispheres — count planets in each hemisphere (houses 1–6 = bottom, 7–12 = top,
  //    4–9 = left, 10–3 = right). Pick the most extreme as dominant.
  const houseOf = SAMPLE_CHART.planets.map(p => p.house);
  const inSet = (h, set) => set.includes(h);
  const TOP_H    = [7,8,9,10,11,12];
  const BOT_H    = [1,2,3,4,5,6];
  const LEFT_H   = [4,5,6,7,8,9];
  const RIGHT_H  = [10,11,12,1,2,3];
  const top    = houseOf.filter(h => inSet(h, TOP_H)).length;
  const bottom = houseOf.filter(h => inSet(h, BOT_H)).length;
  const left   = houseOf.filter(h => inSet(h, LEFT_H)).length;
  const right  = houseOf.filter(h => inSet(h, RIGHT_H)).length;
  SYNTHESIS.hemispheres = { top, bottom, left, right };
  // Pick whichever axis has the bigger asymmetry, then the larger side of that axis.
  const vAxisGap = Math.abs(top - bottom);
  const hAxisGap = Math.abs(left - right);
  let dom;
  if (vAxisGap >= hAxisGap) dom = (bottom >= top) ? 'bottom' : 'top';
  else                       dom = (left >= right) ? 'left' : 'right';
  SYNTHESIS.dominantHemisphere = dom;
  SYNTHESIS.hemisphereInterp   = window.getQuadrant(dom);

  // 7) Stelliums — real title/text templates from interpretations.stelliums
  for (const st of SYNTHESIS.stelliums) {
    const interp = window.getStellium(st.kind);
    st.title = interp?.title || '';
    st.text  = interp?.text  || '';
  }

  // 8) Chart ruler (守護孩子的小天使)
  buildChartRuler();
}

// Run an initial build with empty INTERPRETATIONS so SAMPLE_CHART.big3 etc.
// exist even before fetch resolves (UI just shows blank text).
SAMPLE_CHART.big3 = [];
SAMPLE_CHART.others = [];
buildDerivedChartData();

// Old shim removed — buildDerivedChartData() above handles the planetView mapping
// and pulls interpretation text via lookups.jsx accessors.

// ─── Wheel data convenience — passed to <ChartWheel data={...}> ────────────
const SAMPLE_WHEEL_DATA = {
  planets:    SAMPLE_CHART.planets,
  houseCusps: SAMPLE_CHART.houseCusps,
  ascLon:     SAMPLE_CHART.ascLon,
};

// ─── Brand tokens — wired to CSS custom properties in theme.css ────────────
// Components that read BRAND.* / SERIF / SANS / MONO automatically inherit
// from the production palette. Single source of truth → theme.css. Change a
// hex there and every component updates.
const BRAND = {
  bgDark:    'var(--color-bg-dark, #0D1B2E)',
  bgMid:     'var(--color-bg-mid, #1A3550)',
  glow:      'var(--color-glow, #4A7FA5)',
  blue:      'var(--color-brand-blue, #5B63B7)',
  blueLight: 'var(--color-brand-light, #8B93D4)',
  white:     'var(--color-white, #F0F4F8)',
  gray:      'var(--color-gray, #8A9BB0)',
  gold:      'var(--color-gold, #C9A96E)',
  starWhite: '#E8F0FF',  // not in production palette, used only for star tints
};
const SERIF = 'var(--font-zh, "Noto Serif TC", serif)';
const SANS  = 'var(--font-body, "Noto Sans TC", sans-serif)';
const MONO  = '"JetBrains Mono", "SF Mono", monospace';

Object.assign(window, {
  SAMPLE_CHART, SAMPLE_WHEEL_DATA, SYNTHESIS,
  BRAND, SERIF, SANS, MONO,
  formatDeg, planetView, buildDerivedChartData, buildChartRuler, computeChartRuler,
});
