/* Climate — why the house is this temperature.
   Commit model: INSTANT. Stepping a zone applies immediately with an undo toast;
   boosting is instant; nothing here has a Save.

   Chart-led rather than tabular, because the answer is a chain — who is home,
   who is awake, what each zone was told — and the day strip shows it against the
   clock in one glance. The comfort target is derived in metrics.comfortTarget
   and nothing on this screen stores it. */
(() => {
  const { Button, Badge, Alert, AlertTitle, AlertDescription, Avatar, Switch } = window.OriginDesignSystem_7c998b;

  /* The schedule strip: a zone's own weekday pattern, drawn as a level per hour
     against the derived target. Levels rather than temperatures, because the
     temperature itself is the chain — the strip says when, the dial says what. */
  const SCHEDULES = {
    ground: { warm: [[6, 9], [16, 23]], label: "Mornings and evenings" },
    first: { warm: [[6, 8], [20, 23]], label: "Getting up and going to bed" },
    study: { warm: [[8, 18]], label: "The working day" },
    water: { warm: [[5, 7], [17, 20]], label: "Two heats a day" },
    annexe: { warm: [], label: "Frost protection only" },
  };
  const scheduleLevel = (zoneId, hour) => {
    const schedule = SCHEDULES[zoneId];
    if (!schedule) return 0;
    return schedule.warm.some((span) => hour >= span[0] && hour < span[1]) ? 3 : 1;
  };

  function ZoneCard({ zone, data, now, viewer, onZoneStep, onZoneMode, onNavigate }) {
    const windowOpen = data.entries.filter((e) => e.zone === zone.id && e.status === "open");
    const heatingOpen = ZONE_FLAGS.heatingWithWindowOpen(zone, data.entries);
    const rooms = ROOMS.filter((room) => data.entries.some((e) => e.room === room.value && e.zone === zone.id));
    return (
      <Card fill>
        <div className="hh-room__top">
          <div style={{ minWidth: 0 }}>
            <div className="hh-room__name">{zoneName(zone.id)}</div>
            <div className="hh-footnote">
              {zone.radiators ? zone.radiators + " radiators" : "Cylinder"}
              {rooms.length ? " · " + rooms.map((r) => r.label.toLowerCase()).join(", ") : ""}
            </div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div className="hh-room__temp">{formatTemp(zone.reportedC)}<span>°</span></div>
            <div className="hh-footnote">{zone.targetC == null ? "off" : formatTemp(zone.targetC) + "° wanted"}</div>
          </div>
        </div>

        <span className="hh-actions__row" style={{ marginBottom: "var(--space-3)" }}>
          <StatusBadge values={ZONE_STATUS} value={zone.status} />
          {ZONE_FLAGS.callingForHeat(zone) ? <Badge size="sm" variant="info">Calling for heat</Badge> : null}
          {zone.overrideUntil ? <Badge size="sm" variant="warning">Boost until {formatWhen(zone.overrideUntil, now)}</Badge> : null}
          {heatingOpen ? <Badge size="sm" variant="warning">Window open</Badge> : null}
        </span>

        <DayStrip levelOf={(hour) => scheduleLevel(zone.id, hour)} now={now}
          label={zoneName(zone.id) + " schedule — " + SCHEDULES[zone.id].label.toLowerCase()} />
        <p className="hh-footnote" style={{ marginTop: "var(--space-2)" }}>{SCHEDULES[zone.id].label} · the mark is now</p>

        <div className="hh-room__foot">
          <span className="hh-actions__row">
            {zone.status === "off"
              ? <Button size="sm" variant="outline" onClick={() => onZoneMode(zone, "comfort")}>Turn on</Button>
              : <Button size="sm" variant="outline" onClick={() => onZoneMode(zone, zone.status === "boost" ? "comfort" : "boost")}>{zone.status === "boost" ? "End boost" : "Boost " + HOUSE_POLICY.boostMinutes + " min"}</Button>}
            {windowOpen.length ? <Button size="sm" variant="ghost" onClick={() => onNavigate("/security")}>See the window</Button> : null}
          </span>
          {zone.targetC != null ? (
            <span className="hh-stepper">
              <Button variant="ghost" size="icon-xs" aria-label={"Cooler in " + zoneName(zone.id)} onClick={() => onZoneStep(zone, -0.5)}><Icon name="minus" size={14} /></Button>
              <span style={{ fontSize: "var(--text-xs)", fontVariantNumeric: "tabular-nums", minWidth: "2.6rem", textAlign: "center" }}>{formatTemp(zone.targetC)}°</span>
              <Button variant="ghost" size="icon-xs" aria-label={"Warmer in " + zoneName(zone.id)} onClick={() => onZoneStep(zone, 0.5)}><Icon name="plus" size={14} /></Button>
            </span>
          ) : null}
        </div>
      </Card>
    );
  }

  function ClimateScreen({ data, now, viewer, onNavigate, onZoneStep, onZoneMode, onEditPreference, onExport }) {
    const zones = zoneRows(data, now);
    const target = comfortTarget(data.members, now);
    const setter = comfortSetter(data.members, now);
    const calling = zonesCallingForHeat(data, now);
    const openZones = zonesHeatingWithWindowOpen(data, now);
    const awake = membersAwake(data.members, now);
    const asleep = membersAsleep(data.members, now);
    const heating = data.devices.filter((d) => (d.kind === "thermostat" || d.id === "dev_10") && d.status === "online");
    const heatingWatts = heating.filter((d) => DEVICE_FLAGS.drawing(d)).reduce((n, d) => n + d.watts, 0);

    return (
      <>
        <PageHead path="/climate" title="Climate"
          lede={"The house holds the warmest comfort preference among the people who are home and awake. Right now that is " + formatTemp(target.c) + "° — " + target.because + "."}
          actions={<ExportMenu scope={"All " + zones.length + " zones and their schedules"} onExport={(format) => onExport("Climate", "Zones and schedules", zones.length, format)} />} />

        <Band>
          <Card>
            <div style={{ display: "flex", flexWrap: "wrap", alignItems: "flex-start", justifyContent: "space-between", gap: "var(--space-6)" }}>
              <div style={{ flex: "1 1 26rem", minWidth: 0 }}>
                <h2 className="hh-card__title">Where that number comes from</h2>
                <p className="hh-card__note">
                  Nothing stores it. It is the warmest comfort preference among the people who are home and awake; with everybody asleep the house drops to {formatTemp(HOUSE_POLICY.nightSetbackC)}°, and with nobody home to {formatTemp(HOUSE_POLICY.awaySetbackC)}°. Change somebody's preference and every zone on this screen moves.
                </p>
              </div>
              <div className="hh-dial" style={{ flex: "0 1 12rem", alignItems: "flex-end", textAlign: "right" }}>
                <span className="hh-dial__reading">{formatTemp(target.c)}<span>°</span></span>
                <span className="hh-dial__target" style={{ textAlign: "right" }}>what the house is holding</span>
              </div>
            </div>
            {/* The household in two columns: seven people down one column is a list
                to scan, and the same seven in two is a set to read. */}
            <div className="hh-split" style={{ marginTop: "var(--space-5)", paddingTop: "var(--space-4)", borderTop: "1px solid var(--border)" }}>
              {[0, 1].map((half) => {
                const people = activeMembers(data.members);
                const size = Math.ceil(people.length / 2);
                const slice = people.slice(half * size, half * size + size);
                if (!slice.length) return null;
                return (
                  <Rows key={half}>
                    {slice.map((member) => {
                      const counts = MEMBER_FLAGS.countsForComfort(member, now);
                      const isSetter = setter && setter.id === member.id;
                      return (
                        <Row key={member.id} recessed={!counts}
                          title={<PersonCell name={member.name} avatar={member.avatar} size={26}
                            meta={(member.home ? (MEMBER_FLAGS.isAwake(member, now) ? "home and up" : "home, asleep since " + member.prefs.bedtime) : "out") + " · wants " + formatTemp(member.prefs.comfortC) + "°"}
                            onOpen={() => onNavigate("/people/" + member.id)} />}
                          value={isSetter ? <Badge size="sm" variant="info">Setting the target</Badge> : counts ? <span className="hh-footnote">counts</span> : <span className="hh-footnote">ignored</span>}>
                          <Button variant="ghost" size="xs" onClick={() => onEditPreference(member)}>Change</Button>
                        </Row>
                      );
                    })}
                  </Rows>
                );
              })}
            </div>
          </Card>
        </Band>

        <Figures items={[
          { label: "Zones calling for heat", value: calling.length, unit: "of " + zones.length, qualifier: calling.length ? calling.map((z) => zoneName(z.id).toLowerCase()).join(", ") : "every zone is at temperature" },
          { label: "Coldest zone", value: formatTemp(zones.slice().sort((a, b) => a.reportedC - b.reportedC)[0].reportedC), unit: "°", qualifier: zoneName(zones.slice().sort((a, b) => a.reportedC - b.reportedC)[0].id) + " — " + statusValue(ZONE_STATUS, zones.slice().sort((a, b) => a.reportedC - b.reportedC)[0].status).label.toLowerCase() },
          { label: "Heating draw", value: formatWatts(heatingWatts).split(" ")[0], unit: formatWatts(heatingWatts).split(" ")[1], qualifier: "controllers and the study heater, off the same device list as everything else" },
          { label: "People counted", value: awake.length, qualifier: asleep.length + " asleep and " + (activeMembers(data.members).length - membersHome(data.members).length) + " out, so their preferences are ignored" },
        ]} />

        {openZones.length ? (
          <Band>
            <Card tint>
              <Alert variant="warning">
                <AlertTitle>{openZones.length === 1 ? zoneName(openZones[0].id) + " is heating with a window open" : openZones.length + " zones are heating with a window open"}</AlertTitle>
                <AlertDescription>
                  {openZones.map((zone) => {
                    const open = data.entries.filter((e) => e.zone === zone.id && e.status === "open");
                    return zoneName(zone.id) + " is at " + formatTemp(zone.reportedC) + "° against " + formatTemp(zone.targetC) + "°, and " + open.map((e) => e.label.toLowerCase()).join(" and ") + " has been open since " + formatWhen(open[0].changedAt, now);
                  }).join(". ")}.
                </AlertDescription>
              </Alert>
            </Card>
          </Band>
        ) : null}

        <div className="hh-roomgrid">
          {zones.map((zone) => (
            <ZoneCard key={zone.id} zone={zone} data={data} now={now} viewer={viewer}
              onZoneStep={onZoneStep} onZoneMode={onZoneMode} onNavigate={onNavigate} />
          ))}
        </div>

        <Band>
          <Card tint title="The house's own rules" note="Set in Settings, and read by every zone above.">
            <Pairs items={[
              { label: "Away setback", value: formatTemp(HOUSE_POLICY.awaySetbackC) + "° when nobody is home" },
              { label: "Night setback", value: formatTemp(HOUSE_POLICY.nightSetbackC) + "° once everybody home is asleep" },
              { label: "Frost protection", value: formatTemp(HOUSE_POLICY.frostC) + "° in the annexe" },
              { label: "Boost", value: HOUSE_POLICY.boostMinutes + " minutes, " + formatTemp(1.5) + "° over the target" },
            ]} />
          </Card>
        </Band>
      </>
    );
  }

  Object.assign(window, { ClimateScreen, ZoneCard, SCHEDULES, scheduleLevel });
})();
