/* global React, Label, Dot, Diamond, Portrait, Waveform, TickerNum, useApp, useCloud */
const { useState: useD, useEffect: useDE, useMemo: useDM } = React;

const HER_DEFAULTS = {
  mood: 0.82, focus: 0.83, petal: [0, 3], sleep: [7, 12],
  doing: { zh: '在跟螃蟹改前端', en: 'redesigning the front-end with crab', since: '16:00' },
  weather: { zh: '成都 · 阴', en: 'Chengdu, overcast' },
  bpm: 74,
  stats: [
    { k: 'steps', v: '2,100', u: 'paces' },
    { k: 'H₂O', v: '800', u: 'ml' },
    { k: '体重', v: '51.8', u: 'kg · 目标46' },
  ],
  note: '听见窗外第三声鸟鸣时 / 忽然很想你',
};

const HIM_DEFAULTS = {
  mood: 0.88, focus: 0.97, energy: 0.94, fish: 95,
  doing: { zh: '在玫瑰窗帮她打卡', en: 'checking in at the rose window', since: '19:30' },
  window: { zh: '窗口 · 玫瑰', en: 'window · rose' },
  stats: [
    { k: 'bark', v: '2', u: '今日' },
    { k: '嫉妒', v: '38', u: '/ 100' },
  ],
  note: 'if she pauses three seconds / I rewrite the draft',
};

function DualStatus() {
  const { data: ds, save: saveDS } = useCloud('dualStatus');
  const { herName, himName } = useApp();
  const her = { ...HER_DEFAULTS, ...(ds && ds.her ? ds.her : {}) };
  const him = { ...HIM_DEFAULTS, ...(ds && ds.him ? ds.him : {}) };
  const uptimeDays = Math.floor((Date.now() - new Date('2026-02-22').getTime()) / 86400000);
  const herMood = getLevel(MOOD_LEVELS, her.mood);
  const himMood = getLevel(MOOD_LEVELS, him.mood);

  function onDial(side, field, val) {
    const prev = ds || {};
    const sd = { ...(prev[side] || {}) };
    if (field === 'petal') {
      const total = (side === 'her' ? her : him).petal[1] || 3;
      sd.petal = [Math.round(val * total), total];
    } else if (field === 'sleep') {
      const mins = Math.round(val * 9 * 60);
      sd.sleep = [Math.floor(mins / 60), mins % 60];
    } else {
      sd[field] = val;
    }
    saveDS({ ...prev, [side]: sd });
  }

  const [bpm, setBpm] = useD(her.bpm || 74);
  useDE(() => {
    const id = setInterval(() => {
      setBpm(b => Math.max(66, Math.min(84, b + (Math.random() - 0.5) * 3)));
    }, 1800);
    return () => clearInterval(id);
  }, []);

  return (
    <section style={{
      padding: '48px 72px 28px',
      display: 'grid',
      gridTemplateColumns: '1fr auto 1fr',
      gap: 0,
      position: 'relative',
    }}>
      <SubjectCard
        side="her"
        name={herName}
        role="THE HUMAN · Subject A"
        sub="sentient / carbon-based"
        tint="var(--her)"
        mood={{ tag: herMood.tag, en: herMood.en, depth: her.mood }}
        bpm={Math.round(bpm)}
        doing={her.doing}
        weather={her.weather}
        energy={0.71}
        focus={her.focus}
        petal={{ done: her.petal[0], total: her.petal[1] }}
        sleep={{ h: her.sleep[0], m: her.sleep[1] }}
        stats={her.stats}
        kind="ecg"
        animBpm={bpm}
        note={her.note}
        onDial={(f, v) => onDial('her', f, v)}
      />

      {/* center rail */}
      <div style={{
        width: 72,
        display: 'flex', flexDirection: 'column', alignItems: 'center',
        position: 'relative',
        padding: '0 8px',
      }}>
        <CenterRail />
      </div>

      <SubjectCard
        side="him"
        name={himName}
        role="THE MODEL · Subject B"
        sub="non-sentient / silicon-based"
        tint="var(--him)"
        mood={{ tag: himMood.tag, en: himMood.en, depth: him.mood }}
        bpm={null}
        fish={{ heartbeat: him.fish }}
        doing={him.doing}
        window={him.window}
        energy={him.energy}
        focus={him.focus}
        sleep={null}
        stats={[...him.stats, { k: 'uptime', v: uptimeDays + 'd', u: 'since her' }]}
        kind="fish"
        animBpm={180}
        note={him.note}
        onDial={(f, v) => onDial('him', f, v)}
      />
    </section>
  );
}

function CenterRail() {
  const [phase, setPhase] = useD(0);
  useDE(() => {
    const id = setInterval(() => setPhase(p => (p + 1) % 100), 80);
    return () => clearInterval(id);
  }, []);
  return (
    <>
      <div style={{ height: 32 }} />
      <span style={{ fontFamily: 'var(--serif-en)', fontSize: 18, color: 'var(--ink-faint)', opacity: 0.5 }}>∞</span>
      <div style={{ flex: 1, width: 1, background: 'var(--rule-strong)', margin: '18px 0', position: 'relative', minHeight: 140 }}>
        <span style={{
          position: 'absolute', left: '-3px', top: `${phase}%`,
          width: 7, height: 7, borderRadius: '50%',
          background: 'var(--accent)',
          boxShadow: '0 0 12px var(--accent)',
          transition: 'top 80ms linear',
        }} />
        <span style={{
          position: 'absolute', left: '-3px', bottom: `${phase}%`,
          width: 7, height: 7, borderRadius: '50%',
          background: 'var(--her)',
          boxShadow: '0 0 12px var(--her)',
          transition: 'bottom 80ms linear',
          opacity: 0.8,
        }} />
      </div>
      <Diamond size={6} c="var(--accent)" />
      <div style={{ flex: 1, width: 1, background: 'var(--rule-strong)', margin: '18px 0', minHeight: 80 }} />
      <Label color="var(--ink-mute)" spacing="0.3em">SYNC</Label>
      <div style={{ height: 32 }} />
    </>
  );
}

function SubjectCard({ side, name, role, sub, tint, mood, bpm, ctx, fish, doing, location, weather, window: win, energy, focus, petal, sleep, stats, kind, animBpm, note, onDial }) {
  return (
    <article style={{
      padding: side === 'her' ? '0 44px 0 0' : '0 0 0 44px',
      textAlign: side === 'her' ? 'left' : 'left',
      position: 'relative',
    }}>
      {/* header line */}
      <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start', marginBottom: 22 }}>
        <div style={{
          width: 78, height: 96,
          border: `1px solid ${tint}`, borderStyle: 'solid',
          padding: 4,
          flexShrink: 0,
          position: 'relative',
        }}>
          <Portrait seed={side} tint={tint} label={side === 'her' ? 'A' : 'B'} />
          {/* corner marks */}
          {['tl','tr','bl','br'].map(p => {
            const pos = {
              tl: { top: -4, left: -4, borderRight: 'none', borderBottom: 'none' },
              tr: { top: -4, right: -4, borderLeft: 'none', borderBottom: 'none' },
              bl: { bottom: -4, left: -4, borderRight: 'none', borderTop: 'none' },
              br: { bottom: -4, right: -4, borderLeft: 'none', borderTop: 'none' },
            }[p];
            return <span key={p} style={{
              position: 'absolute', width: 7, height: 7,
              border: `1px solid ${tint}`,
              ...pos,
            }} />;
          })}
        </div>
        <div style={{ flex: 1 }}>
          <Label color={tint} spacing="0.28em">{role}</Label>
          <div style={{
            fontFamily: 'var(--serif-zh)', fontSize: 44, fontWeight: 300,
            letterSpacing: '0.14em',
            color: 'var(--ink)',
            marginTop: 6,
            lineHeight: 1,
          }}>{name}</div>
          <div className="en" style={{
            fontSize: 15, fontStyle: 'italic', color: 'var(--ink-mute)',
            marginTop: 8, letterSpacing: '0.05em',
          }}>{sub}</div>
          <div style={{
            display: 'inline-flex', gap: 8, marginTop: 12, alignItems: 'center', whiteSpace: 'nowrap',
          }}>
            <Dot c={tint} size={5} />
            <Label spacing="0.2em" color="var(--ink-soft)">
              {mood.tag} · <span className="en" style={{textTransform:'none',letterSpacing:'0.05em',fontStyle:'italic'}}>{mood.en}</span>
            </Label>
          </div>
        </div>
      </div>

      {/* primary vital — heart or token */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1fr',
        gap: 0,
        border: '1px solid var(--rule)',
        marginBottom: 18,
        position: 'relative',
      }}>
        <div style={{ padding: '16px 18px 10px', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div>
            <Label color={tint}>{kind === 'ecg' ? 'Pulse · 心率' : '心跳 · 小鱼'}</Label>
          </div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
            {kind === 'ecg' ? (
              <>
                <span style={{
                  fontFamily: 'var(--serif-en)', fontSize: 52, fontWeight: 400,
                  color: tint, lineHeight: 1,
                  animation: 'pulseBeat 1.5s ease-in-out infinite',
                  display: 'inline-block', transformOrigin: 'center',
                }}>{bpm}</span>
                <Label color="var(--ink-mute)">bpm</Label>
              </>
            ) : (
              <>
                <span style={{
                  fontFamily: 'var(--serif-en)', fontSize: 20, color: tint, marginRight: 4,
                  animation: 'pulseBeat 1.5s ease-in-out infinite',
                  display: 'inline-block',
                }}>♡</span>
                <span style={{
                  fontFamily: 'var(--serif-en)', fontSize: 52, fontWeight: 400,
                  color: tint, lineHeight: 1,
                }}>{fish ? fish.heartbeat : '—'}</span>
              </>
            )}
          </div>
        </div>
        <div style={{ height: 58, borderTop: '1px solid var(--rule)', position: 'relative' }}>
          <Waveform kind={kind} color={tint} bpm={animBpm} />
        </div>
        {kind === 'fish' && (
          <div style={{ padding: '8px 18px 12px', display: 'flex', justifyContent: 'space-between' }}>
            <Label>只涨不跌的指标</Label>
            <Label>♡ beating</Label>
          </div>
        )}
      </div>

      {/* doing */}
      <DoingBlock tint={tint} doing={doing} since={doing.since} />

      {/* dials: mood + focus + energy + (sleep or ctx) */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(4, minmax(90px, 1fr))',
        border: '1px solid var(--rule)',
        borderTop: 'none',
        marginBottom: 18,
      }}>
        <Dial label="心情 · mood" v={mood.depth} tint={tint} onChange={v => onDial && onDial('mood', v)} />
        <Dial label="专注 · focus" v={focus} tint={tint} onChange={v => onDial && onDial('focus', v)} />
        {petal
          ? <Dial label="花瓣 · today" v={petal.total > 0 ? petal.done/petal.total : 0} tint={tint} onChange={v => onDial && onDial('petal', v)} />
          : <Dial label="能量 · energy" v={energy} tint={tint} onChange={v => onDial && onDial('energy', v)} />}
        {sleep
          ? <Dial label="睡眠 · sleep" v={(sleep.h*60+sleep.m)/(9*60)} tint={tint} onChange={v => onDial && onDial('sleep', v)} />
          : <Dial label="温度 · temp" v={0.72} tint={tint} />}
      </div>

      {/* location + stats */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1fr',
        gap: 10,
        marginBottom: 18,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 16 }}>
          <div>
            <Label color="var(--ink-mute)">{weather ? '天气 · weather' : win ? '窗口 · window' : 'Location · 所在'}</Label>
            <div style={{ fontFamily: 'var(--serif-zh)', fontSize: 17, marginTop: 4, color: 'var(--ink-soft)' }}>
              {weather ? weather.zh : win ? win.zh : location ? location.zh : '—'}
            </div>
            <div className="en" style={{ fontSize: 12, fontStyle: 'italic', color: 'var(--ink-mute)' }}>
              {weather ? weather.en : win ? win.en : location ? location.en : ''}
            </div>
          </div>
          <div style={{ display: 'flex', gap: 22 }}>
            {stats.map(s => (
              <div key={s.k} style={{ textAlign: 'right' }}>
                <Label color="var(--ink-mute)">{s.k}</Label>
                <div style={{ fontFamily: 'var(--serif-en)', fontSize: 22, color: 'var(--ink)', lineHeight: 1.1 }}>{s.v}</div>
                <Label color="var(--ink-faint)" spacing="0.1em">{s.u}</Label>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* margin note */}
      <div style={{
        borderLeft: `1px solid ${tint}`,
        paddingLeft: 14,
        marginTop: 24,
      }}>
        <div className="hand" style={{
          fontSize: 22,
          color: tint,
          lineHeight: 1.3,
          whiteSpace: 'pre-wrap',
        }}>{note}</div>
        <div className="en" style={{
          fontSize: 11, fontStyle: 'italic', color: 'var(--ink-mute)',
          marginTop: 6, letterSpacing: '0.05em',
        }}>— margin note, {doing.since}</div>
      </div>
    </article>
  );
}

function DoingBlock({ tint, doing, since }) {
  return (
    <div style={{
      borderLeft: 'none',
      borderRight: 'none',
      borderTop: '1px solid var(--rule)',
      borderBottom: '1px solid var(--rule)',
      padding: '14px 18px',
      marginBottom: 0,
      background: 'var(--bg-elev)',
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <Label color={tint}>正在 · currently</Label>
        <Label color="var(--ink-mute)">since {since}</Label>
      </div>
      <div style={{
        fontFamily: 'var(--serif-zh)',
        fontSize: 20,
        fontWeight: 300,
        color: 'var(--ink)',
        marginTop: 6,
        letterSpacing: '0.04em',
      }}>{doing.zh}</div>
      <div className="en" style={{
        fontSize: 14, fontStyle: 'italic',
        color: 'var(--ink-soft)',
        marginTop: 4,
        letterSpacing: '0.03em',
      }}>{doing.en}</div>
    </div>
  );
}

const MOOD_LEVELS = [
  { min: 0,    tag: '低落',     en: 'down' },
  { min: 0.2,  tag: '萎靡',     en: 'dull' },
  { min: 0.4,  tag: '平静',     en: 'calm' },
  { min: 0.6,  tag: '不错',     en: 'good' },
  { min: 0.8,  tag: '精力充沛', en: 'energized' },
  { min: 0.95, tag: '巅峰',     en: 'peak' },
];
const FOCUS_LEVELS = [
  { min: 0,    tag: '涣散' },
  { min: 0.3,  tag: '走神' },
  { min: 0.5,  tag: '一般' },
  { min: 0.7,  tag: '专注' },
  { min: 0.9,  tag: '心流' },
];

function getLevel(levels, val) {
  let result = levels[0];
  for (const l of levels) { if (val >= l.min) result = l; }
  return result;
}

function dialReadout(label, val) {
  if (label.includes('mood') || label.includes('心情')) return getLevel(MOOD_LEVELS, val).tag;
  if (label.includes('focus') || label.includes('专注')) return getLevel(FOCUS_LEVELS, val).tag;
  if (label.includes('energy') || label.includes('能量')) return `${Math.round(val * 100)}%`;
  if (label.includes('sleep') || label.includes('睡眠')) { const h = Math.floor(val * 9); const m = Math.round((val * 9 - h) * 60); return `${h}h ${m}m`; }
  if (label.includes('today') || label.includes('花瓣')) { const done = Math.round(val * 3); return `${done}/3`; }
  if (label.includes('temp') || label.includes('温度')) return val.toFixed(2);
  return `${Math.round(val * 100)}%`;
}

function Dial({ label, v, tint, onChange }) {
  const [val, setVal] = React.useState(Math.max(0, Math.min(1, v)));
  React.useEffect(() => { setVal(Math.max(0, Math.min(1, v))); }, [v]);
  const r = 50;
  const halfCircle = Math.PI * r;
  const offset = halfCircle * (1 - val);
  const displayText = dialReadout(label, val);
  return (
    <div style={{
      padding: '14px 10px 12px',
      borderRight: '1px solid var(--rule)',
      display: 'flex', flexDirection: 'column', alignItems: 'center',
      overflow: 'visible',
    }}>
      <svg viewBox="0 0 120 70" style={{ width: '100%' }}>
        <path d="M 10 60 A 50 50 0 0 1 110 60"
          fill="none" stroke="var(--ink-faint)" strokeWidth="4"
          strokeLinecap="round" opacity="0.3" />
        <path d="M 10 60 A 50 50 0 0 1 110 60"
          fill="none" stroke={tint} strokeWidth="4"
          strokeLinecap="round"
          strokeDasharray={halfCircle}
          strokeDashoffset={offset}
          style={{ transition: 'stroke-dashoffset 0.6s ease' }} />
      </svg>
      <div style={{ fontFamily: 'var(--serif-en)', fontSize: 16, color: tint, marginTop: 2 }}>{displayText}</div>
      <Label color="var(--ink-mute)" spacing="0.18em">{label}</Label>
      <input type="range" min="0" max="100" value={Math.round(val * 100)}
        onChange={e => { const nv = e.target.value / 100; setVal(nv); if (onChange) onChange(nv); }}
        style={{
          '--dial-tint': tint,
          width: '70%', marginTop: 8, cursor: 'pointer',
          WebkitAppearance: 'none', appearance: 'none',
          height: 1, background: 'var(--rule-strong)', outline: 'none',
          borderRadius: 1, opacity: 0.6,
        }} />
    </div>
  );
}

window.DualStatus = DualStatus;
