// app/screen-settings.jsx — Avatar ▸ Settings. Unit system, default planning
// servings, and the ingredient-price DB (the prices the cost engine uses).

const setLabel = { fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
  letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--ink-3)' };
const setInput = { width: '100%', padding: '11px 13px', borderRadius: 9, background: 'rgba(0,0,0,0.3)',
  border: '1px solid var(--hairline)', color: 'var(--ink)', fontFamily: 'Bricolage Grotesque',
  fontSize: 14, outline: 'none', boxSizing: 'border-box' };

function Segmented({ options, value, onChange }) {
  return (
    <div style={{ display: 'inline-flex', padding: 3, borderRadius: 999, background: 'rgba(255,255,255,0.04)',
      border: '1px solid var(--hairline)' }}>
      {options.map(([v, label]) => {
        const on = v === value;
        return (
          <button key={v} onClick={() => onChange(v)} style={{ fontFamily: 'Bricolage Grotesque',
            fontSize: 13, fontWeight: 600, padding: '8px 18px', borderRadius: 999, cursor: 'pointer', border: 'none',
            background: on ? 'linear-gradient(180deg, rgba(240,168,80,0.92), rgba(217,135,40,0.92))' : 'transparent',
            color: on ? '#1a1208' : 'var(--ink-3)' }}>{label}</button>
        );
      })}
    </div>
  );
}

function SettingsCard({ children, style }) {
  return <div style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid var(--hairline)',
    borderRadius: 16, padding: 24, ...style }}>{children}</div>;
}

function SettingsRow({ title, sub, children }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 20,
      flexWrap: 'wrap', padding: '14px 0' }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontFamily: 'Bricolage Grotesque', fontSize: 15.5, fontWeight: 600, color: 'var(--ink)' }}>{title}</div>
        {sub && <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 13.5, color: 'var(--ink-3)', marginTop: 2 }}>{sub}</div>}
      </div>
      <div style={{ flexShrink: 0 }}>{children}</div>
    </div>
  );
}

const blankItem = () => ({ key: '', name: '', unit: 'g', packSize: '', packCost: '', isStaple: false, aliases: '', source: 'You' });

function IngredientEditor({ item, onSave, onCancel, isMobile }) {
  const [f, setF] = React.useState(() => ({
    ...item, packSize: item.packSize ?? '', packCost: item.packCost ?? '',
    aliases: Array.isArray(item.aliases) ? item.aliases.join(', ') : (item.aliases || '') }));
  const upd = (k, v) => setF((p) => ({ ...p, [k]: v }));
  const valid = f.name.trim() && Number(f.packSize) > 0 && Number(f.packCost) >= 0;
  const save = () => onSave({
    key: f.key || undefined, name: f.name.trim(), unit: f.unit,
    packSize: Number(f.packSize), packCost: Number(f.packCost), isStaple: !!f.isStaple,
    aliases: f.aliases.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean),
    source: f.source || 'You' });
  return (
    <div style={{ padding: '18px 18px', background: 'rgba(240,168,80,0.05)',
      border: '1px solid rgba(240,168,80,0.3)', borderRadius: 12, display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '2fr 1fr', gap: 12 }}>
        <div><label style={setLabel}>Name</label><input value={f.name} autoFocus
          onChange={(e) => upd('name', e.target.value)} placeholder="Olive oil" style={{ ...setInput, marginTop: 6 }} /></div>
        <div><label style={setLabel}>Unit</label>
          <select value={f.unit} onChange={(e) => upd('unit', e.target.value)} style={{ ...setInput, marginTop: 6 }}>
            <option value="g">grams (g)</option><option value="ml">millilitres (ml)</option><option value="each">each</option>
          </select></div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <div><label style={setLabel}>Pack size ({f.unit})</label><input value={f.packSize} type="number"
          onChange={(e) => upd('packSize', e.target.value)} placeholder="750" style={{ ...setInput, marginTop: 6 }} /></div>
        <div><label style={setLabel}>Pack cost ($)</label><input value={f.packCost} type="number"
          onChange={(e) => upd('packCost', e.target.value)} placeholder="9.00" style={{ ...setInput, marginTop: 6 }} /></div>
      </div>
      <div><label style={setLabel}>Also known as <span style={{ textTransform: 'none', letterSpacing: 0,
        fontFamily: 'Spectral', fontStyle: 'italic', color: 'var(--ink-4)' }}>comma separated — used to match recipe lines</span></label>
        <input value={f.aliases} onChange={(e) => upd('aliases', e.target.value)}
          placeholder="olive oil, evoo" style={{ ...setInput, marginTop: 6 }} /></div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap' }}>
        <button onClick={() => upd('isStaple', !f.isStaple)} style={{ display: 'inline-flex', alignItems: 'center',
          gap: 9, background: 'transparent', border: 'none', cursor: 'pointer', padding: 0, textAlign: 'left' }}>
          <span style={{ width: 20, height: 20, borderRadius: 5, flexShrink: 0,
            border: f.isStaple ? 'none' : '1.5px solid var(--ink-3)',
            background: f.isStaple ? 'linear-gradient(135deg, #f0a850, #c97818)' : 'transparent',
            color: '#1a1208', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            {f.isStaple && <Icon.check size={12} stroke={3} />}</span>
          <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 14, color: 'var(--ink-2)' }}>
            Pantry staple <span style={{ color: 'var(--ink-3)' }}>(kept off the shopping list — still costed)</span></span>
        </button>
        {!isMobile && <span style={{ flex: 1 }} />}
        {Number(f.packSize) > 0 && Number(f.packCost) >= 0 && (
          <span style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--ink-3)' }}>
            = {window.LCDomain.fmtMoney(Number(f.packCost) / Number(f.packSize))} / {f.unit}</span>
        )}
      </div>
      <div style={{ display: 'flex', gap: 10 }}>
        <FButton size="m" onClick={save} style={valid ? (isMobile ? { flex: 1 } : {}) : { opacity: 0.5, pointerEvents: 'none', flex: isMobile ? 1 : undefined }}>Save</FButton>
        <FButton size="m" variant="ghost" onClick={onCancel} style={isMobile ? { flex: 1 } : {}}>Cancel</FButton>
      </div>
    </div>
  );
}

function IngredientRow({ item, onEdit, onDelete, selected, onToggleSelect, isMobile }) {
  const unitCost = item.packSize ? item.packCost / item.packSize : (item.unitCost || 0);
  const checkbox = (
    <button onClick={onToggleSelect} title="Select to merge" style={{ width: 22, height: 22, borderRadius: 6,
      flexShrink: 0, cursor: 'pointer', padding: 0,
      border: selected ? 'none' : '1.5px solid var(--ink-3)',
      background: selected ? 'linear-gradient(135deg, #f0a850, #c97818)' : 'transparent',
      color: '#1a1208', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>
      {selected && <Icon.check size={13} stroke={3} />}
    </button>
  );
  const nameLine = (
    <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, flexWrap: 'wrap' }}>
      <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>{item.name}</span>
      {item.isStaple && <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 9, fontWeight: 600,
        letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--ink-3)', padding: '2px 7px',
        borderRadius: 999, border: '1px solid var(--hairline)' }}>staple</span>}
    </div>
  );
  const sub = (
    <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 12.5, color: 'var(--ink-3)', marginTop: 2 }}>
      {window.LCDomain.fmtMoney(item.packCost)} / {item.packSize}{item.unit} · {item.source || 'AI'}{item.date ? ` · ${item.date}` : ''}
    </div>
  );
  const unit = (
    <span style={{ fontFamily: 'var(--mono)', fontSize: 12.5, color: 'var(--ink-2)', whiteSpace: 'nowrap' }}>
      {window.LCDomain.fmtMoney(unitCost)}<span style={{ color: 'var(--ink-4)' }}>/{item.unit}</span></span>
  );
  const editBtn = (
    <button onClick={onEdit} title="Edit" style={{ width: 34, height: 34, borderRadius: 999, cursor: 'pointer',
      background: 'rgba(255,255,255,0.04)', border: '1px solid var(--hairline)', color: 'var(--ink-2)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon.edit size={14} /></button>
  );
  const delBtn = (
    <button onClick={onDelete} title="Remove" style={{ width: 34, height: 34, borderRadius: 999, cursor: 'pointer',
      background: 'transparent', border: '1px solid var(--hairline)', color: 'var(--ink-3)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon.trash size={14} /></button>
  );

  if (isMobile) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '12px 2px',
        borderTop: '1px solid var(--hairline-2)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          {checkbox}
          <div style={{ flex: 1, minWidth: 0 }}>{nameLine}</div>
          {unit}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingLeft: 34 }}>
          <div style={{ flex: 1, minWidth: 0 }}>{sub}</div>
          {editBtn}{delBtn}
        </div>
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '12px 4px',
      borderTop: '1px solid var(--hairline-2)' }}>
      {checkbox}
      <div style={{ flex: 1, minWidth: 0 }}>{nameLine}{sub}</div>
      {unit}{editBtn}{delBtn}
    </div>
  );
}

function MergeDialog({ items, onConfirm, onClose, isMobile }) {
  const [primaryKey, setPrimaryKey] = React.useState(items[0] ? items[0].key : null);
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 300, background: 'rgba(6,6,8,0.62)',
      backdropFilter: 'blur(6px)', display: 'flex', alignItems: isMobile ? 'flex-end' : 'center',
      justifyContent: 'center', padding: isMobile ? 0 : 24 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: '100%', maxWidth: isMobile ? '100%' : 460,
        maxHeight: isMobile ? '92%' : '90%', overflowY: 'auto',
        background: 'rgba(20,20,24,0.98)', border: '1px solid var(--hairline)',
        borderRadius: isMobile ? '22px 22px 0 0' : 20,
        boxShadow: '0 40px 100px rgba(0,0,0,0.7)', padding: isMobile ? '22px 20px 28px' : 26, boxSizing: 'border-box' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 7, fontFamily: 'Bricolage Grotesque',
          fontSize: 10, fontWeight: 600, letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--olive)' }}>
          Merge {items.length} ingredients
        </div>
        <h2 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: 24, letterSpacing: '-0.03em',
          color: 'var(--ink)', margin: '10px 0 0', lineHeight: 1.1 }}>
          Keep one<span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400, color: 'var(--olive)' }}> — fold the rest in.</span>
        </h2>
        <p style={{ fontFamily: 'Spectral', fontSize: 14, color: 'var(--ink-3)', margin: '8px 0 18px', lineHeight: 1.5 }}>
          The others' names and aliases become aliases of the one you keep, then they're removed. Recipes re-match to the kept item's price.
        </p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {items.map((it) => {
            const on = it.key === primaryKey;
            const unitCost = it.packSize ? it.packCost / it.packSize : (it.unitCost || 0);
            return (
              <button key={it.key} onClick={() => setPrimaryKey(it.key)} style={{ display: 'flex', alignItems: 'center',
                gap: 12, padding: '12px 14px', borderRadius: 12, cursor: 'pointer', textAlign: 'left',
                background: on ? 'rgba(240,168,80,0.10)' : 'rgba(255,255,255,0.03)',
                border: on ? '1px solid rgba(240,168,80,0.45)' : '1px solid var(--hairline)' }}>
                <span style={{ width: 18, height: 18, borderRadius: 999, flexShrink: 0,
                  border: on ? '5px solid var(--olive)' : '2px solid var(--ink-3)', boxSizing: 'border-box' }} />
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ display: 'block', fontFamily: 'Bricolage Grotesque', fontSize: 15, fontWeight: 600,
                    color: 'var(--ink)' }}>{it.name}{on && <span style={{ color: 'var(--olive)', fontWeight: 500 }}> · keep</span>}</span>
                  <span style={{ display: 'block', fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 12.5,
                    color: 'var(--ink-3)', marginTop: 1 }}>{window.LCDomain.fmtMoney(it.packCost)} / {it.packSize}{it.unit} · {window.LCDomain.fmtMoney(unitCost)}/{it.unit}</span>
                </span>
              </button>
            );
          })}
        </div>
        <div style={{ marginTop: 22, display: 'flex', gap: 10, justifyContent: isMobile ? 'stretch' : 'flex-end' }}>
          <FButton size="m" variant="ghost" onClick={onClose} style={isMobile ? { flex: 1 } : {}}>Cancel</FButton>
          <FButton size="m" onClick={() => onConfirm(primaryKey)} style={isMobile ? { flex: 1.4 } : {}}>Merge into one</FButton>
        </div>
      </div>
    </div>
  );
}

function SettingsScreen() {
  const { layout, back, settings, setSettings, ingredientCosts, saveIngredientCost, deleteIngredientCost } = useApp();
  const isMobile = layout === 'mobile';
  const [q, setQ] = React.useState('');
  const [editing, setEditing] = React.useState(null);   // key being edited, or '__new__'
  const [selected, setSelected] = React.useState(() => new Set());
  const [merging, setMerging] = React.useState(false);
  const list = (ingredientCosts || []).filter((it) =>
    !q || (it.name + ' ' + (it.aliases || []).join(' ')).toLowerCase().includes(q.toLowerCase()))
    .sort((a, b) => (a.name || '').localeCompare(b.name || ''));

  const onSave = async (item) => { await saveIngredientCost(item); setEditing(null); };
  const toggleSel = (key) => setSelected((s) => { const n = new Set(s); n.has(key) ? n.delete(key) : n.add(key); return n; });
  const clearSel = () => setSelected(new Set());
  const selectedItems = (ingredientCosts || []).filter((it) => selected.has(it.key));
  const doMerge = async (primaryKey) => {
    const primary = selectedItems.find((i) => i.key === primaryKey);
    if (!primary) { setMerging(false); return; }
    const others = selectedItems.filter((i) => i.key !== primaryKey);
    const aliasSet = new Set((primary.aliases || []).map((a) => a.toLowerCase()));
    others.forEach((o) => {
      (o.aliases || []).forEach((a) => aliasSet.add(a.toLowerCase()));
      if (o.name) aliasSet.add(o.name.toLowerCase());
    });
    await saveIngredientCost({ ...primary, aliases: [...aliasSet] });
    for (const o of others) { await deleteIngredientCost(o.key); }   // eslint-disable-line no-await-in-loop
    clearSel(); setMerging(false);
  };
  const pad = isMobile ? '24px 18px 60px' : '40px 48px 80px';

  return (
    <Shell tab="recipes">
      <div style={{ padding: isMobile ? '20px 18px' : '24px 48px', display: 'flex', alignItems: 'center',
        gap: 16, borderBottom: '1px solid var(--hairline)' }}>
        <button onClick={back} style={{ background: 'transparent', border: 'none', cursor: 'pointer',
          fontFamily: 'Bricolage Grotesque', fontSize: 13, fontWeight: 500, color: 'var(--ink-3)', padding: 0 }}>← Back</button>
        <span style={{ flex: 1 }} />
        <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
          letterSpacing: '0.24em', textTransform: 'uppercase', color: 'var(--ink-4)' }}>Settings</span>
      </div>

      <div style={{ padding: pad }}>
        <div style={{ maxWidth: 760, margin: '0 auto' }}>
          <h1 style={{ fontFamily: 'Bricolage Grotesque', fontWeight: 700, fontSize: isMobile ? 40 : 60,
            lineHeight: 0.95, letterSpacing: '-0.045em', color: 'var(--ink)', margin: '0 0 32px' }}>
            Settings<span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontWeight: 400, color: 'var(--olive)' }}>.</span>
          </h1>

          {/* Preferences */}
          <SettingsCard style={{ marginBottom: 22 }}>
            <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
              letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>Preferences</span>
            <div style={{ marginTop: 8 }}>
              <SettingsRow title="Units" sub="How quantities are shown across recipes.">
                <Segmented options={[['metric', 'Metric'], ['imperial', 'Imperial']]}
                  value={settings.unitSystem} onChange={(v) => setSettings({ unitSystem: v })} />
              </SettingsRow>
              <div style={{ height: 1, background: 'var(--hairline-2)' }} />
              <SettingsRow title="Default planning servings" sub="New planned meals start at this many serves.">
                <ServeStepper value={settings.defaultPlanningServings || 2}
                  onChange={(n) => setSettings({ defaultPlanningServings: n })} />
              </SettingsRow>
            </div>
          </SettingsCard>

          {/* Ingredient prices */}
          <SettingsCard>
            <div style={{ display: 'flex', alignItems: isMobile ? 'stretch' : 'flex-end',
              flexDirection: isMobile ? 'column' : 'row',
              justifyContent: 'space-between', gap: 16 }}>
              <div>
                <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 10, fontWeight: 600,
                  letterSpacing: '0.28em', textTransform: 'uppercase', color: 'var(--olive)' }}>Ingredient prices</span>
                <div style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 14, color: 'var(--ink-3)', marginTop: 6 }}>
                  The prices the cost estimator uses · {(ingredientCosts || []).length} items
                </div>
              </div>
              <FButton size="m" onClick={() => setEditing('__new__')}
                style={isMobile ? { width: '100%' } : {}}><Icon.plus size={15} />Add ingredient</FButton>
            </div>

            {editing === '__new__' && (
              <div style={{ marginTop: 18 }}>
                <IngredientEditor item={blankItem()} onSave={onSave} onCancel={() => setEditing(null)} isMobile={isMobile} />
              </div>
            )}

            <div style={{ marginTop: 18, display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px',
              background: 'rgba(255,255,255,0.04)', border: '1px solid var(--hairline)', borderRadius: 999 }}>
              <Icon.search size={16} style={{ color: 'var(--ink-3)' }} />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="search ingredients"
                style={{ border: 'none', background: 'transparent', outline: 'none', flex: 1,
                  fontFamily: 'Bricolage Grotesque', fontSize: 14, color: 'var(--ink)' }} />
            </div>

            {selected.size > 0 && (
              <div style={{ marginTop: 16, display: 'flex', alignItems: isMobile ? 'stretch' : 'center',
                flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 10 : 12, padding: '12px 16px',
                borderRadius: 12, background: 'rgba(240,168,80,0.08)', border: '1px solid rgba(240,168,80,0.3)' }}>
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flex: 1 }}>
                  <span style={{ fontFamily: 'Bricolage Grotesque', fontSize: 13.5, fontWeight: 600, color: 'var(--ink)' }}>
                    {selected.size} selected</span>
                  <span style={{ fontFamily: 'Spectral', fontStyle: 'italic', fontSize: 13, color: 'var(--ink-3)' }}>
                    {selected.size < 2 ? 'pick one more to merge' : 'merge duplicates into one'}</span>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, justifyContent: 'flex-end' }}>
                  <button onClick={clearSel} style={{ background: 'transparent', border: 'none', cursor: 'pointer',
                    color: 'var(--ink-3)', fontFamily: 'Bricolage Grotesque', fontSize: 13, fontWeight: 500 }}>Clear</button>
                  <FButton size="s" onClick={() => setMerging(true)}
                    style={selected.size < 2 ? { opacity: 0.5, pointerEvents: 'none' } : {}}>Merge…</FButton>
                </div>
              </div>
            )}

            <div style={{ marginTop: 8 }}>
              {list.length === 0 && (
                <div style={{ padding: '32px 0', textAlign: 'center', fontFamily: 'Spectral', fontStyle: 'italic',
                  fontSize: 16, color: 'var(--ink-3)' }}>No ingredients match “{q}”.</div>
              )}
              {list.map((it) => editing === it.key ? (
                <div key={it.key} style={{ padding: '12px 0', borderTop: '1px solid var(--hairline-2)' }}>
                  <IngredientEditor item={it} onSave={onSave} onCancel={() => setEditing(null)} isMobile={isMobile} />
                </div>
              ) : (
                <IngredientRow key={it.key} item={it} selected={selected.has(it.key)} isMobile={isMobile}
                  onToggleSelect={() => toggleSel(it.key)}
                  onEdit={() => setEditing(it.key)} onDelete={() => deleteIngredientCost(it.key)} />
              ))}
            </div>
          </SettingsCard>
        </div>
      </div>

      {merging && <MergeDialog items={selectedItems} onConfirm={doMerge} onClose={() => setMerging(false)} isMobile={isMobile} />}
    </Shell>
  );
}

Object.assign(window, { SettingsScreen });
