// Screens.jsx — Home, Recipe, Weigh
const { useState: useStateS, useEffect: useEffectS, useMemo: useMemoS, useRef: useRefS } = React;

// ──────────────────────────────────────────────────────────
// Shared atoms
// ──────────────────────────────────────────────────────────
function IconBack({ color, size = 24 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M15 18l-6-6 6-6" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function IconCheck({ color, size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M4 12l5 5L20 6" stroke={color} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function IconPlus({ color, size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M12 5v14M5 12h14" stroke={color} strokeWidth="2.6" strokeLinecap="round"/>
    </svg>
  );
}
function IconMinus({ color, size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M5 12h14" stroke={color} strokeWidth="2.6" strokeLinecap="round"/>
    </svg>
  );
}
function IconArrowRight({ color, size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      <path d="M5 12h14M13 5l7 7-7 7" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

function TopBar({ theme, title, leading, trailing }) {
  return (
    <div style={{
      padding: '56px 16px 12px', display: 'flex', alignItems: 'center',
      gap: 12, flexShrink: 0, background: theme.bg,
    }}>
      <div style={{ width: 44 }}>{leading}</div>
      <div style={{
        flex: 1, textAlign: 'center',
        fontFamily: theme.fontFamily,
        fontWeight: theme.titleWeight,
        fontSize: 19 * theme.scale,
        color: theme.ink,
        letterSpacing: theme.fontFamilyNum.includes('Mono') ? 0 : 0.5,
      }}>{title}</div>
      <div style={{ width: 44, display: 'flex', justifyContent: 'flex-end' }}>{trailing}</div>
    </div>
  );
}

function PillButton({ theme, onClick, children, style = {}, variant = 'primary', disabled }) {
  const isPrimary = variant === 'primary';
  const bg = disabled
    ? theme.accentSoft
    : (isPrimary ? theme.accent : theme.surface);
  const fg = disabled
    ? theme.inkMute
    : (isPrimary ? (theme.accent === '#FFD429' ? '#1A1A1A' : '#fff') : theme.ink);
  return (
    <button
      onClick={disabled ? undefined : onClick}
      style={{
        border: 'none', background: bg, color: fg,
        padding: '18px 24px', borderRadius: theme.cardRadius + 8,
        fontSize: 17 * theme.scale, fontWeight: 700,
        fontFamily: theme.fontFamilyUi,
        cursor: disabled ? 'default' : 'pointer',
        boxShadow: isPrimary && !disabled ? '0 2px 0 rgba(0,0,0,0.12)' : 'none',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        gap: 10, width: '100%',
        ...style,
      }}
    >{children}</button>
  );
}

// ──────────────────────────────────────────────────────────
// HOME
// ──────────────────────────────────────────────────────────
function HomeScreen({ theme, onOpen, qtys, session, onMenu }) {
  const grouped = useMemoS(() => {
    const out = {};
    for (const r of RECIPES) {
      // don't show companions as separate entries
      const isCompanion = RECIPES.some(x => x.companions?.some(c => c.id === r.id));
      if (isCompanion) continue;
      if (!out[r.category]) out[r.category] = [];
      out[r.category].push(r);
    }
    return out;
  }, []);

  return (
    <>
      <div style={{
        padding: '56px 24px 0', flexShrink: 0,
        display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12,
      }}>
        <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontSize: 13 * theme.scale, letterSpacing: 2, color: theme.inkMute,
          textTransform: 'uppercase', fontWeight: 600, marginBottom: 8,
          fontFamily: theme.fontFamilyUi,
        }}>CELEBREAD · 2026{session ? ` · ${session.display_name}` : ''}</div>
        <h1 style={{
          margin: 0,
          fontSize: 34 * theme.scale,
          fontFamily: theme.fontFamily,
          fontWeight: theme.titleWeight,
          color: theme.ink,
          letterSpacing: theme.fontFamily.includes('Serif') ? 0 : -0.5,
          lineHeight: 1.15,
        }}>配方清單</h1>
        <div style={{
          marginTop: 6, fontSize: 15 * theme.scale, color: theme.inkSoft,
        }}>選擇麵包 → 輸入顆數 → 開始秤量</div>
        </div>
        {onMenu && (
          <button onClick={onMenu} style={{
            width: 44, height: 44, borderRadius: 22, border: 'none', flexShrink: 0,
            background: theme.surface, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            marginTop: 4,
          }}>
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
              <path d="M4 7h16M4 12h16M4 17h16" stroke={theme.ink} strokeWidth="2.4" strokeLinecap="round"/>
            </svg>
          </button>
        )}
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 16px 32px' }}>
        {CATEGORIES.map(cat => grouped[cat] && (
          <div key={cat} style={{ marginBottom: 24 }}>
            <div style={{
              padding: '8px 12px 10px', fontSize: 12 * theme.scale,
              fontWeight: 700, color: theme.inkMute, letterSpacing: 1.5,
              textTransform: 'uppercase', fontFamily: theme.fontFamilyUi,
            }}>{cat}</div>
            <div style={{
              background: theme.surface, borderRadius: theme.cardRadius,
              overflow: 'hidden',
              border: theme.name === '乾淨工業' ? `1px solid ${theme.divider}` : 'none',
            }}>
              {grouped[cat].map((r, idx) => {
                const qty = qtys[r.id];
                return (
                  <button key={r.id} onClick={() => onOpen(r.id)} style={{
                    display: 'flex', alignItems: 'center', gap: 14,
                    width: '100%', padding: '18px 18px',
                    background: 'none', border: 'none', cursor: 'pointer',
                    borderBottom: idx < grouped[cat].length - 1 ? `1px solid ${theme.divider}` : 'none',
                    textAlign: 'left',
                    fontFamily: theme.fontFamilyUi, color: theme.ink,
                  }}>
                    <div style={{
                      width: 44 * theme.scale, height: 44 * theme.scale,
                      borderRadius: theme.cardRadius - 4,
                      background: theme.surfaceAlt,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      fontSize: 24 * theme.scale, flexShrink: 0,
                    }}>{r.emoji}</div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{
                        fontSize: 19 * theme.scale, fontWeight: 600,
                        fontFamily: theme.fontFamily, color: theme.ink,
                        marginBottom: 2,
                      }}>{r.name}</div>
                      <div style={{
                        fontSize: 13 * theme.scale, color: theme.inkSoft,
                      }}>
                        {r.absolute ? `1倍 ≈ ${r.batchUnit}g` : `每顆 ${r.perPieceFlour}g 粉`}
                        {r.companions && <span> · 可搭 {r.companions.map(c => getRecipe(c.id)?.name).filter(Boolean).join('、')}</span>}
                      </div>
                    </div>
                    {qty > 0 && (
                      <div style={{
                        padding: '4px 10px', borderRadius: 999,
                        background: theme.accentSoft, color: theme.accent,
                        fontSize: 13 * theme.scale, fontWeight: 700,
                        fontFamily: theme.fontFamilyNum,
                      }}>{qty}{r.absolute ? '倍' : '顆'}</div>
                    )}
                    <IconArrowRight color={theme.inkMute} size={18} />
                  </button>
                );
              })}
            </div>
          </div>
        ))}
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────
// RECIPE — quantity input + live preview
// ──────────────────────────────────────────────────────────
function Stepper({ theme, value, onChange, suffix = '顆', min = 0, max = 999 }) {
  const dec = () => onChange(Math.max(min, (value || 0) - 1));
  const inc = () => onChange(Math.min(max, (value || 0) + 1));
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 12,
      background: theme.surface, borderRadius: theme.cardRadius,
      padding: 8, border: theme.name === '乾淨工業' ? `1px solid ${theme.divider}` : 'none',
    }}>
      <button onClick={dec} style={{
        width: 56 * theme.scale, height: 56 * theme.scale, borderRadius: theme.cardRadius - 4,
        background: theme.surfaceAlt, border: 'none', cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}><IconMinus color={theme.ink} size={22 * theme.scale} /></button>
      <div style={{ flex: 1, textAlign: 'center' }}>
        <div style={{
          fontSize: 48 * theme.scale, fontWeight: theme.numberWeight,
          fontFamily: theme.fontFamilyNum,
          color: theme.ink, lineHeight: 1, letterSpacing: -1,
        }}>{value || 0}</div>
        <div style={{
          fontSize: 12 * theme.scale, color: theme.inkMute,
          marginTop: 2, letterSpacing: 1,
        }}>{suffix}</div>
      </div>
      <button onClick={inc} style={{
        width: 56 * theme.scale, height: 56 * theme.scale, borderRadius: theme.cardRadius - 4,
        background: theme.accent, border: 'none', cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0,
      }}><IconPlus color={theme.accent === '#FFD429' ? '#1A1A1A' : '#fff'} size={22 * theme.scale} /></button>
    </div>
  );
}

function NumPad({ theme, onPress }) {
  const keys = ['1','2','3','4','5','6','7','8','9','C','0','⌫'];
  return (
    <div style={{
      display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)',
      gap: 8, padding: 0,
    }}>
      {keys.map(k => (
        <button key={k} onClick={() => onPress(k)} style={{
          height: 52 * theme.scale,
          background: theme.surface, border: 'none',
          borderRadius: theme.cardRadius - 4, cursor: 'pointer',
          fontFamily: theme.fontFamilyNum,
          fontSize: 22 * theme.scale, fontWeight: 600,
          color: theme.ink,
        }}>{k}</button>
      ))}
    </div>
  );
}

function RecipeScreen({ theme, recipes, qtys, setQty, onBack, onGo }) {
  const main = recipes[0];
  const totalFlour = recipes.reduce((s, r) => s + r.perPieceFlour * (qtys[r.id] || 0), 0);
  const totalPieces = recipes.reduce((s, r) => s + (qtys[r.id] || 0), 0);
  const hasQty = recipes.some(r => (qtys[r.id] || 0) > 0);

  const press = (targetId) => (k) => {
    const cur = String(qtys[targetId] || 0);
    let next = cur;
    if (k === 'C') next = '0';
    else if (k === '⌫') next = cur.slice(0, -1) || '0';
    else if (/\d/.test(k)) next = (cur === '0' ? k : cur + k);
    const n = parseInt(next, 10) || 0;
    setQty(targetId, Math.min(999, n));
  };

  const [focused, setFocused] = useStateS(main.id);

  const titleStr = recipes.length > 1
    ? `${main.name} + ${recipes.length - 1}款`
    : main.name;

  return (
    <>
      <TopBar
        theme={theme}
        title={titleStr}
        leading={
          <button onClick={onBack} style={{
            width: 44, height: 44, borderRadius: 22, border: 'none',
            background: theme.surface, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><IconBack color={theme.ink} /></button>
        }
      />

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 16px 20px' }}>
        <div style={{
          padding: '6px 4px 14px',
          fontSize: 13 * theme.scale, color: theme.inkSoft,
          fontFamily: theme.fontFamilyUi,
        }}>今天要做幾顆？{recipes.length > 1 && '（不需要的就放0）'}</div>

        {recipes.map((r, idx) => (
          <div key={r.id} onClick={() => setFocused(r.id)} style={{
            outline: focused === r.id ? `2px solid ${theme.accent}` : 'none',
            outlineOffset: 3, borderRadius: theme.cardRadius,
            marginBottom: 14,
          }}>
            <div style={{
              padding: idx === 0 ? '12px 4px 10px' : '8px 4px 10px',
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <div style={{ fontSize: 22 * theme.scale }}>{r.emoji}</div>
              <div style={{
                fontSize: 17 * theme.scale, fontWeight: 600,
                fontFamily: theme.fontFamily, color: theme.ink,
              }}>{r.name}</div>
              <div style={{ flex: 1 }} />
              <div style={{ fontSize: 12 * theme.scale, color: theme.inkMute }}>
                {r.absolute
                  ? `1倍 ≈ ${r.batchUnit}g`
                  : `每顆 ${r.perPieceFlour}g 粉${idx > 0 ? ' · 合併打' : ''}`}
              </div>
            </div>
            <Stepper
              theme={theme}
              value={qtys[r.id] || 0}
              onChange={(v) => setQty(r.id, v)}
              suffix={r.absolute ? '倍' : '顆'}
            />
          </div>
        ))}

        {/* Numpad (acts on focused) */}
        <div style={{ marginTop: 8 }}>
          <div style={{
            fontSize: 11 * theme.scale, letterSpacing: 1.5, color: theme.inkMute,
            padding: '12px 4px 8px', textTransform: 'uppercase',
          }}>
            數字鍵盤 · 輸入 {recipes.find(r => r.id === focused)?.name}
          </div>
          <NumPad theme={theme} onPress={press(focused)} />
        </div>

        {/* Summary tile */}
        {hasQty && !main.absolute && (
          <div style={{
            marginTop: 18, padding: '18px 20px',
            background: theme.surface, borderRadius: theme.cardRadius,
            display: 'flex', alignItems: 'center', gap: 14,
            border: theme.name === '乾淨工業' ? `1px solid ${theme.divider}` : 'none',
          }}>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12 * theme.scale, color: theme.inkMute, letterSpacing: 1, textTransform: 'uppercase' }}>總粉量</div>
              <div style={{
                fontSize: 30 * theme.scale, fontWeight: theme.numberWeight,
                fontFamily: theme.fontFamilyNum, color: theme.ink, lineHeight: 1,
                marginTop: 4,
              }}>{Math.round(totalFlour)}<span style={{ fontSize: 16 * theme.scale, color: theme.inkMute, marginLeft: 4 }}>g</span></div>
            </div>
            <div style={{ width: 1, height: 36, background: theme.divider }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12 * theme.scale, color: theme.inkMute, letterSpacing: 1, textTransform: 'uppercase' }}>總顆數</div>
              <div style={{
                fontSize: 30 * theme.scale, fontWeight: theme.numberWeight,
                fontFamily: theme.fontFamilyNum, color: theme.ink, lineHeight: 1,
                marginTop: 4,
              }}>{totalPieces}<span style={{ fontSize: 16 * theme.scale, color: theme.inkMute, marginLeft: 4 }}>顆</span></div>
            </div>
          </div>
        )}
      </div>

      <div style={{ padding: '10px 16px 34px', background: theme.bg, flexShrink: 0 }}>
        <PillButton theme={theme} onClick={onGo} disabled={!hasQty}>
          開始秤量
          <IconArrowRight color={theme.accent === '#FFD429' ? '#1A1A1A' : '#fff'} size={20} />
        </PillButton>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────
// WEIGH — checklist
// ──────────────────────────────────────────────────────────
function WeighScreen({ theme, recipes, qtys, merged, checked, toggle, onBack, onDone }) {
  const allItems = merged.sections.flatMap(s => s.items.map(i => ({ ...i, section: s.title })));
  const doneCount = allItems.filter(i => checked[i.section + '|' + i.name]).length;
  const total = allItems.length;
  const pct = total ? Math.round(doneCount / total * 100) : 0;

  const titleStr = recipes.map(r => `${r.name} ${qtys[r.id] || 0}${r.absolute ? '倍' : '顆'}`).join(' + ');

  return (
    <>
      <TopBar
        theme={theme}
        title={titleStr}
        leading={
          <button onClick={onBack} style={{
            width: 44, height: 44, borderRadius: 22, border: 'none',
            background: theme.surface, cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><IconBack color={theme.ink} /></button>
        }
      />

      {/* progress */}
      <div style={{ padding: '0 20px 12px', flexShrink: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 6 }}>
          <div style={{ fontSize: 12 * theme.scale, color: theme.inkMute, letterSpacing: 1, textTransform: 'uppercase' }}>已秤 {doneCount} / {total}</div>
          <div style={{
            fontSize: 15 * theme.scale, fontWeight: 700,
            fontFamily: theme.fontFamilyNum, color: pct === 100 ? theme.success : theme.ink,
          }}>{pct}%</div>
        </div>
        <div style={{ height: 6, background: theme.surfaceAlt, borderRadius: 999, overflow: 'hidden' }}>
          <div style={{
            width: pct + '%', height: '100%',
            background: pct === 100 ? theme.success : theme.accent,
            transition: 'width .25s ease',
          }} />
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '0 16px 20px' }}>
        {merged.sections.map(section => (
          <div key={section.title} style={{ marginBottom: 20 }}>
            <div style={{
              padding: '8px 12px 10px', fontSize: 12 * theme.scale,
              fontWeight: 700, color: theme.inkMute, letterSpacing: 1.5,
              textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between',
            }}>
              <span>{section.title}</span>
              {section.totalLabel && (
                <span style={{ color: theme.ink, fontFamily: theme.fontFamilyNum }}>
                  {section.totalLabel} {Math.round(section.total)}g
                </span>
              )}
            </div>
            <div style={{
              background: theme.surface, borderRadius: theme.cardRadius,
              overflow: 'hidden',
              border: theme.name === '乾淨工業' ? `1px solid ${theme.divider}` : 'none',
            }}>
              {section.items.map((item, idx) => {
                const key = section.title + '|' + item.name;
                const isChecked = !!checked[key];
                return (
                  <button key={key} onClick={() => toggle(key)} style={{
                    display: 'flex', alignItems: 'center', gap: 16,
                    width: '100%', padding: '18px 18px',
                    background: isChecked ? theme.accentSoft : 'none', border: 'none', cursor: 'pointer',
                    borderBottom: idx < section.items.length - 1 ? `1px solid ${theme.divider}` : 'none',
                    textAlign: 'left', fontFamily: theme.fontFamilyUi,
                    transition: 'background .15s ease',
                  }}>
                    <div style={{
                      width: 32 * theme.scale, height: 32 * theme.scale, borderRadius: 8,
                      border: `2px solid ${isChecked ? theme.accent : theme.inkMute}`,
                      background: isChecked ? theme.accent : 'transparent',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      flexShrink: 0,
                    }}>{isChecked && <IconCheck color={theme.accent === '#FFD429' ? '#1A1A1A' : '#fff'} size={20} />}</div>
                    <div style={{
                      flex: 1, minWidth: 0,
                      fontSize: 18 * theme.scale, fontWeight: 600,
                      color: isChecked ? theme.inkSoft : theme.ink,
                      textDecoration: isChecked ? 'line-through' : 'none',
                      fontFamily: theme.fontFamily,
                    }}>{item.name}</div>
                    <div style={{ textAlign: 'right', flexShrink: 0 }}>
                      <div style={{
                        fontSize: 26 * theme.scale, fontWeight: theme.numberWeight,
                        fontFamily: theme.fontFamilyNum,
                        color: isChecked ? theme.inkMute : theme.ink,
                        lineHeight: 1, letterSpacing: -0.5,
                      }}>{fmt(item.amount, item.precise)}
                      <span style={{ fontSize: 14 * theme.scale, color: theme.inkMute, marginLeft: 4, fontWeight: 500 }}>
                        {item.unit || 'g'}
                      </span></div>
                    </div>
                  </button>
                );
              })}
            </div>
          </div>
        ))}

        {/* breakdown footer */}
        {merged.recipeBreakdown && merged.recipeBreakdown.length > 1 && (
          <div style={{
            padding: '14px 18px', marginTop: 6,
            background: theme.surfaceAlt, borderRadius: theme.cardRadius,
            fontSize: 13 * theme.scale, color: theme.inkSoft,
          }}>
            <div style={{ fontWeight: 700, color: theme.ink, marginBottom: 6 }}>分割參考</div>
            {merged.recipeBreakdown.map(({ r, n }) => n > 0 && (
              <div key={r.id} style={{ display: 'flex', justifyContent: 'space-between', padding: '3px 0' }}>
                <span>{r.name} × {n}</span>
                <span style={{ fontFamily: theme.fontFamilyNum, color: theme.ink }}>
                  {r.splitWeight ? `${r.splitWeight}g / 顆` : `${r.perPieceFlour}g 粉 / 顆`}
                </span>
              </div>
            ))}
          </div>
        )}
      </div>

      <div style={{ padding: '10px 16px 34px', background: theme.bg, flexShrink: 0 }}>
        <PillButton theme={theme} onClick={onDone} variant={pct === 100 ? 'primary' : 'secondary'}>
          {pct === 100 ? '✓ 全部秤好，回配方列表' : '完成'}
        </PillButton>
      </div>
    </>
  );
}

Object.assign(window, { HomeScreen, RecipeScreen, WeighScreen });
