// appliance-art.jsx — Expressive animated SVG appliances for the Home screen.
// Each appliance has 3 states: off, on, struggling. Animations are pure CSS.
// All scale via the `size` prop; default 72px square.

const __APP_CSS = `
@keyframes ap-blow   { 0%,100%{opacity:.2;transform:translateY(0)} 50%{opacity:.9;transform:translateY(2px)} }
@keyframes ap-glow   { 0%,100%{opacity:.45} 50%{opacity:1} }
@keyframes ap-drip   { 0%{opacity:0;transform:translateY(-4px)} 30%{opacity:1} 100%{opacity:0;transform:translateY(8px)} }
@keyframes ap-frost  { 0%,100%{opacity:.6} 50%{opacity:1} }
@keyframes ap-wave1  { 0%{transform:translateX(0)} 100%{transform:translateX(-10px)} }
@keyframes ap-spin   { to{transform:rotate(360deg)} }
@keyframes ap-bob    { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-1.5px)} }
@keyframes ap-flow   { 0%{stroke-dashoffset:14} 100%{stroke-dashoffset:0} }
@keyframes ap-pulse  { 0%,100%{transform:scale(1);opacity:1} 50%{transform:scale(1.12);opacity:.85} }
.ap-blow  { animation: ap-blow 1.4s ease-in-out infinite; }
.ap-blow2 { animation: ap-blow 1.4s ease-in-out infinite; animation-delay: .35s; }
.ap-blow3 { animation: ap-blow 1.4s ease-in-out infinite; animation-delay: .7s; }
.ap-glow  { animation: ap-glow 2.2s ease-in-out infinite; }
.ap-drip  { animation: ap-drip 1.6s ease-in infinite; }
.ap-frost { animation: ap-frost 3s ease-in-out infinite; }
.ap-wave  { animation: ap-wave1 1.2s linear infinite; }
.ap-bob   { animation: ap-bob 2.8s ease-in-out infinite; }
.ap-fan   { animation: ap-spin 1.6s linear infinite; transform-origin: center; }
.ap-fan-slow { animation: ap-spin 3.4s linear infinite; transform-origin: center; }
.ap-flow-line { animation: ap-flow 0.7s linear infinite; }
.ap-src-pulse { animation: ap-pulse 1.6s ease-in-out infinite; transform-origin: center; }
@keyframes ap-pipe { to{stroke-dashoffset:-12} }
.ap-pipe-flow { animation: ap-pipe 0.55s linear infinite; }
`;

if (typeof document !== 'undefined' && !document.getElementById('appliance-art-css')) {
  const s = document.createElement('style');
  s.id = 'appliance-art-css';
  s.textContent = __APP_CSS;
  document.head.appendChild(s);
}

// AC — vents blow, fan spins. Struggling = red tint + fast fan.
function ACArt({ size = 72, state = 'on', tone }) {
  const blowing = state !== 'off';
  const stress = state === 'struggling';
  const body = tone?.bg || '#E5EFE5';
  const accent = stress ? '#B85C4A' : (tone?.fg || '#2E6B4A');
  return (
    <div style={{ width: size, height: size, position: 'relative' }} className="ap-bob">
      <svg viewBox="0 0 80 80" width={size} height={size}>
        <rect x="8" y="20" width="64" height="28" rx="6" fill={body} stroke={accent} strokeWidth="2" strokeOpacity="0.4" />
        {/* vents */}
        <rect x="14" y="32" width="52" height="2" rx="1" fill={accent} opacity="0.4" />
        <rect x="14" y="38" width="52" height="2" rx="1" fill={accent} opacity="0.4" />
        {/* status light */}
        <circle cx="62" cy="26" r="2" fill={blowing ? (stress ? '#B85C4A' : '#4A8964') : '#C4BDA8'} className={blowing ? 'ap-glow' : ''} />
        {/* blowing air */}
        {blowing && (
          <g stroke={accent} strokeWidth="2.4" strokeLinecap="round" fill="none">
            <path d="M 22 54 q 4 4 0 8" className="ap-blow" />
            <path d="M 32 56 q 4 4 0 10" className="ap-blow2" />
            <path d="M 42 54 q 4 4 0 8" className="ap-blow3" />
            <path d="M 52 56 q 4 4 0 10" className="ap-blow" />
            <path d="M 62 54 q 4 4 0 8" className="ap-blow2" />
          </g>
        )}
      </svg>
    </div>
  );
}

// Water heater — pill-shaped tank with rising heat lines. Struggling = bubbles.
function WaterHeaterArt({ size = 72, state = 'on', tone }) {
  const on = state !== 'off';
  const stress = state === 'struggling';
  const body = tone?.bg || '#E2ECF3';
  const accent = stress ? '#B85C4A' : (tone?.fg || '#345070');
  return (
    <div style={{ width: size, height: size, position: 'relative' }} className="ap-bob">
      <svg viewBox="0 0 80 80" width={size} height={size}>
        {/* tank */}
        <rect x="22" y="18" width="36" height="50" rx="6" fill={body} stroke={accent} strokeWidth="2" strokeOpacity="0.4" />
        {/* water level */}
        <rect x="24" y={on ? 30 : 56} width="32" height={on ? 36 : 10} rx="3" fill={accent} opacity={on ? 0.4 : 0.18}
              style={{ transition: 'all .35s ease' }} />
        {/* heat element */}
        <line x1="30" y1="64" x2="50" y2="64" stroke={on ? (stress ? '#B85C4A' : '#C99A3E') : '#C4BDA8'} strokeWidth="3" strokeLinecap="round" className={on ? 'ap-glow' : ''} />
        {/* status dot */}
        <circle cx="52" cy="24" r="2" fill={on ? (stress ? '#B85C4A' : '#4A8964') : '#C4BDA8'} className={on ? 'ap-glow' : ''} />
        {/* steam */}
        {on && (
          <g stroke={accent} strokeWidth="2" strokeLinecap="round" fill="none" opacity="0.6">
            <path d="M 32 14 q 2 -4 0 -8" className="ap-blow" />
            <path d="M 40 12 q 2 -4 0 -8" className="ap-blow2" />
            <path d="M 48 14 q 2 -4 0 -8" className="ap-blow3" />
          </g>
        )}
      </svg>
    </div>
  );
}

// Fridge — always on. Frost shimmer animation. Status pip indicates good/bad.
function FridgeArt({ size = 72, state = 'on', tone }) {
  const stress = state === 'struggling';
  const body = tone?.bg || '#E8DCC4';
  const accent = tone?.fg || '#5A4A22';
  return (
    <div style={{ width: size, height: size, position: 'relative' }} className="ap-bob">
      <svg viewBox="0 0 80 80" width={size} height={size}>
        <rect x="22" y="10" width="36" height="60" rx="5" fill={body} stroke={accent} strokeWidth="2" strokeOpacity="0.4" />
        {/* divider */}
        <line x1="22" y1="28" x2="58" y2="28" stroke={accent} strokeWidth="2" strokeOpacity="0.4" />
        {/* handles */}
        <rect x="26" y="18" width="2" height="6" rx="1" fill={accent} opacity="0.7" />
        <rect x="26" y="40" width="2" height="10" rx="1" fill={accent} opacity="0.7" />
        {/* frost dots — top compartment */}
        <g fill={stress ? '#B85C4A' : '#7A9CB8'} className="ap-frost">
          <circle cx="34" cy="22" r="1.2" />
          <circle cx="40" cy="20" r="1" />
          <circle cx="46" cy="23" r="1.4" />
        </g>
        {/* status pip */}
        <circle cx="52" cy="14" r="1.8" fill={stress ? '#B85C4A' : '#4A8964'} className="ap-glow" />
      </svg>
    </div>
  );
}

Object.assign(window, { ACArt, WaterHeaterArt, FridgeArt });

// ─────────────────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────────────────
// PowerFlow — compact "house is drawing power" strip that reads as flowing
// straight out of the battery above it. Devices are GROUPED BY KIND (three
// aircons collapse into one "AC ×3" node) so the strip stays one short row no
// matter how many devices exist. Display-first: a quick glance at what's live.
//
// Props:
//   c        — palette
//   devices  — [{ key, kind, name, watts, on, lockedOn }]
//   kinds    — DEVICE_KINDS(c) map: { [kind]: { Icon, tone } }
//   onToggleKind — (kind) => void; tap a live group to cut its power
// ─────────────────────────────────────────────────────────────────────────
function PowerFlow({ c, menuC, devices, kinds, onToggleKind, onToggleDevice }) {
  const [openKind, setOpenKind] = React.useState(null);
  // Popover surfaces use `menuC` (a guaranteed-opaque palette) so the sheet
  // stays readable even when the strip sits on a translucent dark card.
  const mc = menuC || c;
  // Group ON devices by kind → one node each. Locked-on background loads
  // (e.g. the fridge) are excluded — the strip highlights what you can act on.
  const groups = {};
  for (const d of devices) {
    if (!d.on || d.watts <= 0 || d.lockedOn) continue;
    const g = groups[d.kind] || (groups[d.kind] = { kind: d.kind, watts: 0, count: 0, locked: false, items: [] });
    g.watts += d.watts; g.count += 1; g.items.push(d);
  }
  const list = Object.values(groups).sort((a, b) => b.watts - a.watts);
  const totalW = list.reduce((s, g) => s + g.watts, 0);
  const flowing = list.length > 0;

  // Close popover on any outside tap.
  React.useEffect(() => {
    if (!openKind) return undefined;
    const close = () => setOpenKind(null);
    window.addEventListener('click', close);
    return () => window.removeEventListener('click', close);
  }, [openKind]);

  // All-on devices for a kind that still exist (for popover live state).
  const kindDevices = (kind) => devices.filter(d => d.kind === kind && d.on && d.watts > 0);

  return (
    <div style={{ position: 'relative', marginTop: 8 }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        background: c.surfaceAlt, borderRadius: 12, padding: '7px 10px',
        position: 'relative',
      }}>
        {/* SOURCE — a pipe that curves down out of the battery above and
            carries the live draw out into the house. Extends upward past the
            strip so it visually plugs into the battery's underside. */}
        <div style={{ position: 'relative', width: 34, height: 28, flexShrink: 0 }}>
          <svg width="34" height="68" viewBox="0 0 34 68" fill="none"
               style={{ position: 'absolute', left: 0, bottom: 0, overflow: 'visible' }}>
            {/* pipe casing — the tube walls */}
            <path d="M 10 4 L 10 40 Q 10 54 24 54 L 34 54" stroke={c.border} strokeWidth="9" strokeLinecap="round" />
            {/* inlet socket where it meets the battery */}
            <circle cx="10" cy="4" r="5.5" fill={c.border} />
            {flowing ? (
              <>
                {/* faint energy glow */}
                <path d="M 10 4 L 10 40 Q 10 54 24 54 L 34 54" stroke={c.primary} strokeOpacity="0.25"
                      strokeWidth="7" strokeLinecap="round" strokeDasharray="4 8" className="ap-pipe-flow" />
                {/* bright energy core */}
                <path d="M 10 4 L 10 40 Q 10 54 24 54 L 34 54" stroke={c.primary}
                      strokeWidth="4.5" strokeLinecap="round" strokeDasharray="4 8" className="ap-pipe-flow" />
                {/* live tap at the battery */}
                <circle cx="10" cy="4" r="3" fill={c.primary} />
              </>
            ) : (
              <path d="M 10 4 L 10 40 Q 10 54 24 54 L 34 54" stroke={c.textLight} strokeOpacity="0.5"
                    strokeWidth="3" strokeLinecap="round" strokeDasharray="1 7" />
            )}
          </svg>
        </div>

        {!flowing ? (
          <div style={{ flex: 1, fontSize: 12.5, fontWeight: 600, color: c.textLight }}>House is idle</div>
        ) : (
          <>
            {/* single horizontal row of group chips — scrolls, never wraps */}
            <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 6, minWidth: 0, overflowX: 'visible' }}>
              {list.map((g) => {
                const k = kinds[g.kind];
                const multi = g.count > 1;
                // Single tappable device → toggle directly. Multi → expand popover.
                const interactive = !g.locked && (onToggleDevice || onToggleKind);
                const onClick = (e) => {
                  if (!interactive) return;
                  e.stopPropagation();
                  if (multi && onToggleDevice) {
                    setOpenKind(openKind === g.kind ? null : g.kind);
                  } else if (onToggleKind) {
                    onToggleKind(g.kind);
                  }
                };
                return (
                  <div key={g.kind} style={{ position: 'relative', flexShrink: 0 }}>
                    <button
                      onClick={onClick}
                      disabled={!interactive}
                      aria-label={multi ? `Show ${g.kind} units` : interactive ? `Turn off ${g.kind}` : g.kind}
                      style={{
                        display: 'flex', alignItems: 'center', gap: 4, padding: '4px 8px 4px 4px',
                        background: openKind === g.kind ? k.tone.bg : c.surface,
                        borderRadius: 999, border: openKind === g.kind ? `1px solid ${k.tone.fg}44` : '1px solid transparent',
                        boxShadow: '0 1px 2px rgba(20,30,25,0.05)',
                        cursor: interactive ? 'pointer' : 'default', fontFamily: 'inherit',
                        WebkitTapHighlightColor: 'transparent',
                      }}>
                      <div style={{ width: 20, height: 20, borderRadius: 6, background: k.tone.bg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                        <k.Icon size={13} color={k.tone.fg} />
                      </div>
                      {multi && (
                        <span style={{ fontSize: 10.5, fontWeight: 800, color: k.tone.fg, fontVariantNumeric: 'tabular-nums' }}>×{g.count}</span>
                      )}
                      {g.locked
                        ? <IcLock size={9} color={c.textLight} />
                        : multi && <IcChevD size={11} color={c.textMuted} style={{ transform: openKind === g.kind ? 'rotate(180deg)' : 'none', transition: 'transform .18s' }} />}
                    </button>

                    {/* EXPANDED POPOVER — per-unit toggles */}
                    {openKind === g.kind && multi && (
                      <div onClick={(e) => e.stopPropagation()} style={{
                        position: 'absolute', bottom: 'calc(100% + 8px)', left: '50%', transform: 'translateX(-50%)',
                        width: 208, background: mc.surface, borderRadius: 14, padding: 8,
                        boxShadow: '0 10px 30px rgba(20,30,25,0.22), 0 0 0 1px rgba(20,30,25,0.06)',
                        zIndex: 999, animation: 'm-fadeup .15s ease',
                      }}>
                        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '2px 6px 8px' }}>
                          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                            <k.Icon size={14} color={k.tone.fg} />
                            <span style={{ fontSize: 12.5, fontWeight: 700, color: mc.text, textTransform: 'capitalize' }}>{g.kind === 'ac' ? 'Aircon' : g.kind}</span>
                          </div>
                          <span style={{ fontSize: 11, fontWeight: 700, color: mc.textMuted, fontVariantNumeric: 'tabular-nums' }}>{kindDevices(g.kind).length} on</span>
                        </div>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                          {g.items.map((d) => (
                            <div key={d.key} style={{
                              display: 'flex', alignItems: 'center', gap: 8, padding: '7px 8px',
                              background: mc.surfaceAlt, borderRadius: 10,
                            }}>
                              <div style={{ flex: 1, minWidth: 0 }}>
                                <div style={{ fontSize: 12.5, fontWeight: 600, color: mc.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.name}</div>
                                <div style={{ fontSize: 10.5, color: mc.textMuted, fontVariantNumeric: 'tabular-nums' }}>{d.watts}W</div>
                              </div>
                              {d.lockedOn ? (
                                <IcLock size={12} color={mc.textLight} />
                              ) : (
                                <button
                                  onClick={() => {
                                    onToggleDevice(d.key);
                                    // Close if this was the last on-unit of the kind.
                                    if (kindDevices(g.kind).length <= 1) setOpenKind(null);
                                  }}
                                  aria-label={`Turn off ${d.name}`}
                                  style={{
                                    height: 26, padding: '0 10px', border: 'none', borderRadius: 8,
                                    background: k.tone.bg, color: k.tone.fg, fontFamily: 'inherit',
                                    fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                                    display: 'flex', alignItems: 'center', gap: 4,
                                  }}>
                                  Turn off
                                </button>
                              )}
                            </div>
                          ))}
                        </div>
                        {/* turn-all footer */}
                        {!g.locked && (
                          <button
                            onClick={() => { onToggleKind && onToggleKind(g.kind); setOpenKind(null); }}
                            style={{
                              width: '100%', marginTop: 6, height: 30, border: 'none', borderRadius: 9,
                              background: 'transparent', color: mc.danger, fontFamily: 'inherit',
                              fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                            }}>
                            Turn all off
                          </button>
                        )}
                        {/* pointer */}
                        <div style={{ position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%) rotate(45deg)', width: 10, height: 10, background: mc.surface, marginTop: -5, boxShadow: '2px 2px 4px rgba(20,30,25,0.06)' }} />
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
            {/* total readout */}
            <div style={{ flexShrink: 0, fontSize: 13.5, fontWeight: 800, color: c.text, fontVariantNumeric: 'tabular-nums', lineHeight: 1, paddingLeft: 2 }}>
              {(totalW / 1000).toFixed(2)}<span style={{ fontSize: 9.5, color: c.textMuted, fontWeight: 600 }}>kW</span>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// Inject the traveling-dot keyframe once (needs a real left-to-right translate).
if (typeof document !== 'undefined' && !document.getElementById('ap-flow-dot-css')) {
  const s = document.createElement('style');
  s.id = 'ap-flow-dot-css';
  s.textContent = `@keyframes ap-flow-dot { 0%{left:0;opacity:0} 12%{opacity:1} 88%{opacity:1} 100%{left:100%;opacity:0} }`;
  document.head.appendChild(s);
}

Object.assign(window, { PowerFlow });
