/* Today — the house in one view. Commit model: INSTANT. Every control here
   applies on its own and raises an undo toast where the change is consequential;
   there is no Save on this screen.

   A verdict card first, because the question somebody opens this app with at
   seven in the evening is "is the house all right". Then four figures, then two
   column stacks: what the house is doing, and what wants a person. Every list
   runs its own predicate from metrics.js — none of them is a slice. */
(() => {
  const { Button, Badge, Alert, AlertTitle, AlertDescription, Avatar } = window.OriginDesignSystem_7c998b;

  function VerdictCard({ data, now, viewer, onNavigate, onArm }) {
    const verdict = securityVerdict(data, now);
    const insecure = entriesInsecure(data, now);
    const target = comfortTarget(data.members, now);
    const setter = comfortSetter(data.members, now);
    const home = membersHome(data.members);
    const window_ = windowAt(now);
    const upcoming = nextWindow(now);
    return (
      <Card>
        <div style={{ display: "flex", flexWrap: "wrap", alignItems: "flex-start", justifyContent: "space-between", gap: "var(--space-5)" }}>
          <div style={{ minWidth: 0, flex: "1 1 20rem" }}>
            <span className="hh-actions__row" style={{ marginBottom: "var(--space-2)" }}>
              <StatusBadge values={ALARM_STATUS} value={data.house.alarm} />
              <span className="hh-footnote">changed {formatWhen(data.house.alarmChangedAt, now)} by {memberName(data.members, data.house.alarmChangedById)}</span>
            </span>
            <VerdictLine verdict={verdict} />
            <p className="hh-card__note">{verdict.detail}</p>
            <span className="hh-actions__row" style={{ marginTop: "var(--space-4)" }}>
              {insecure.length ? <Button size="sm" onClick={() => onNavigate("/security")}>Open security</Button> : null}
              <Transitions transitions={armTransitions(data, viewer)} onRun={onArm} />
            </span>
          </div>
          <div className="hh-dial" style={{ flex: "0 1 14rem", alignItems: "flex-end", textAlign: "right" }}>
            <span className="hh-dial__reading">{formatTemp(zoneTarget(data.zones.find((z) => z.id === "ground"), data.members, now))}<span>°</span></span>
            <span className="hh-dial__target" style={{ textAlign: "right" }}>
              Holding {formatTemp(target.c)}° downstairs — {target.because}
              {setter ? <> · <button type="button" className="hh-linkbtn" onClick={() => onNavigate("/people/" + setter.id)}>{setter.name.split(" ")[0]}'s preference</button></> : null}
            </span>
          </div>
        </div>
        <div style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: "var(--space-4)", marginTop: "var(--space-5)", paddingTop: "var(--space-4)", borderTop: "1px solid var(--border)" }}>
          <span className="hh-person" style={{ gap: "var(--space-2)" }}>
            {home.map((member) => (
              <FloatingTip key={member.id} label={member.name + " — " + (MEMBER_FLAGS.isAwake(member, now) ? "up" : "asleep") + (member.where ? ", " + roomName(member.where).toLowerCase() : "")} side="bottom">
                <span style={{ display: "inline-flex" }}><Avatar size={30} src={member.avatar} alt={member.name} fallback={initialsOf(member.name)} /></span>
              </FloatingTip>
            ))}
          </span>
          <span className="hh-footnote" style={{ flex: 1, minWidth: "12rem" }}>
            {home.length} home, {membersAwake(data.members, now).length} up · {activeMembers(data.members).length - home.length} out ·{" "}
            <button type="button" className="hh-linkbtn" onClick={() => onNavigate("/people")}>the household</button>
          </span>
          <span className="hh-footnote">
            {window_.label} rate, {window_.pencePerKwh}p · {upcoming.window.label.toLowerCase()} in {Math.floor(upcoming.minutesAway / 60)}h {upcoming.minutesAway % 60}m
          </span>
        </div>
      </Card>
    );
  }

  /* Arming is a house-level transition, so it lives beside the house rather than
     in enums' per-entity sets: what is offered depends on the alarm and on
     whether anything is open. */
  function armTransitions(data, viewer) {
    const may = ROLE_CAN_ARM[viewer.role];
    const blocking = entriesBlockingArming(data.entries);
    const gate = (t) => Object.assign({}, t,
      !may ? { disabled: true, disabledReason: "Arming the house is an adult's decision. You are signed in as " + labelOf(HOUSEHOLD_ROLES, viewer.role).toLowerCase() + "." }
        : blocking.length && t.id !== "disarm" ? { disabled: true, disabledReason: blocking.map((e) => e.label).join(" and ") + " " + (blocking.length === 1 ? "is" : "are") + " not shut, so the alarm would fault immediately." } : {});
    if (data.house.alarm === "disarmed") return [gate({ id: "arm_home", label: "Arm — home", primary: true }), gate({ id: "arm_away", label: "Arm — away" })];
    if (data.house.alarm === "triggered") return [gate({ id: "disarm", label: "Disarm", primary: true }), { id: "call_response", label: "Call Sentinel Response" }];
    if (data.house.alarm === "fault") return [gate({ id: "clear_fault", label: "Clear the fault", primary: true })];
    return [gate({ id: "disarm", label: "Disarm", primary: true })];
  }

  function TodayScreen({ data, now, viewer, onNavigate, onArm, onToggleDevice, onDeviceTransition, onRequest, onJobTransition, onExport }) {
    const insecure = entriesInsecure(data, now);
    const today = energyToday(data.energy);
    const draw = drawByRoom(data.devices);
    const rooms = roomRows(data, now);
    const needy = devicesNeedingYou(data.devices);
    const waiting = requestsWaiting(data.requests);
    const jobs = jobRows(data, now);
    const overdue = jobsOverdue(jobs);
    const nextJob = jobsBooked(jobs).slice().sort((a, b) => (a.scheduledAt || 0) - (b.scheduledAt || 0))[0];
    const routines = routineRows(data, now);
    const brokenRoutines = routinesNeedingYou(routines);
    const leak = leakVerdict(data.water);
    const advice = batteryAdvice(data.battery, now);
    const windowOpenZones = zonesHeatingWithWindowOpen(data, now);
    const events = eventsNewestFirst(data.events).slice(0, 6);

    return (
      <>
        <PageHead path="/" title="Today"
          lede={new Date(now).toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" }) + " · " + RESIDENCE.name + " · dark since " + HOUSE_POLICY.darkAfter}
          actions={<ExportMenu scope={"Today at " + RESIDENCE.short} onExport={(format) => onExport("Today", "The house as it stands at " + new Date(now).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" }), 1, format)} />} />

        <Band><VerdictCard data={data} now={now} viewer={viewer} onNavigate={onNavigate} onArm={onArm} /></Band>

        <Figures items={[
          { label: "Drawing now", value: formatWatts(liveWatts(data.devices)).split(" ")[0], unit: formatWatts(liveWatts(data.devices)).split(" ")[1], qualifier: devicesDrawing(data.devices).length + " devices on, most of it in the " + (draw[0] ? draw[0].label.toLowerCase() : "house") },
          { label: "Used today", value: formatKwh(today.kwh), unit: "kWh", qualifier: formatPounds(dayCost(today)) + " so far · " + Math.round(today.offPeakShare * 100) + "% of it off-peak" },
          { label: "Wants a person", value: needy.length + waiting.length + overdue.length, qualifier: needy.length + " devices, " + waiting.length + " requests, " + overdue.length + " jobs past their date" },
          { label: "Owed this month", value: formatPounds(billsOutstanding(data.bills)), qualifier: billsDue(data.bills).length + " bills to pay, " + billsOverdue(data.bills, now).length + " past due" },
        ]} />

        <div className="hh-cols hh-cols--wide">
          <div>
            <Card title="What the house is doing" note="Every device drawing power now, grouped by the room it is in.">
              <Rows>
                {draw.map((row) => (
                  <Row key={row.room} title={row.label} value={formatWatts(row.watts)}
                    note={row.devices.map((d) => d.name.toLowerCase()).join(", ")}>
                    <span style={{ width: "6rem" }}>
                      <Bar percent={(row.watts / Math.max(1, liveWatts(data.devices))) * 100} label={row.label + " share of the live draw"} />
                    </span>
                  </Row>
                ))}
              </Rows>
              <div style={{ marginTop: "var(--space-4)", paddingTop: "var(--space-3)", borderTop: "1px solid var(--border)" }} className="hh-footnote">
                {advice.line} — {advice.detail}. <button type="button" className="hh-linkbtn" onClick={() => onNavigate("/energy")}>Energy</button>
              </div>
            </Card>

            <Card title={"Rooms with somebody in them (" + rooms.filter((r) => r.people.length).length + ")"}
              note="Read from where each person's phone last reported, against the devices in that room."
              actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/rooms")}>All rooms</Button>}>
              <Rows>
                {rooms.filter((room) => room.people.length).map((room) => (
                  <Row key={room.room} title={room.label}
                    note={room.people.map((p) => p.name.split(" ")[0] + (MEMBER_FLAGS.isAwake(p, now) ? "" : ", asleep")).join(" and ") + " · " + room.on.length + " of " + room.devices.length + " devices on"}
                    value={room.zone ? formatTemp(room.zone.reportedC) + "°" : null}>
                    <span className="hh-footnote">{formatWatts(room.watts)}</span>
                  </Row>
                ))}
              </Rows>
            </Card>

            <Card flush title={"Just now (" + events.length + " of " + data.events.length + ")"}
              note="The newest entries in the house log."
              actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/log")}>Whole log</Button>}>
              <div style={{ paddingInline: "var(--card-pad)" }}>
                <Rows>
                  {events.map((event) => (
                    <Row key={event.id}
                      title={<button type="button" className="hh-linkbtn" onClick={() => onNavigate(eventRoute(event))}>{event.line}</button>}
                      note={(event.actorId ? memberName(data.members, event.actorId) + " · " : "") + (event.note || labelOf(EVENT_KINDS, event.kind))}
                      value={<span className="hh-footnote" title={formatAbsolute(event.at)}>{formatWhen(event.at, now)}</span>} />
                  ))}
                </Rows>
              </div>
            </Card>
          </div>

          <div>
            {waiting.length ? (
              <Card title={"Waiting on you (" + waiting.length + ")"} note="Somebody in the house asked for something the rules do not let them do.">
                <Rows>
                  {waiting.map((request) => {
                    const member = memberById(data.members, request.memberId);
                    return (
                      <Row key={request.id}
                        title={<PersonCell name={member.name} avatar={member.avatar} size={26} meta={labelOf(HOUSEHOLD_ROLES, member.role) + " · asked " + formatWhen(request.askedAt, now)} onOpen={() => onNavigate("/people/" + member.id)} />}
                        note={"“" + request.body + "”"}>
                        <Transitions transitions={requestTransitions(request, viewer)} onRun={(t) => onRequest(request, t)} />
                      </Row>
                    );
                  })}
                </Rows>
              </Card>
            ) : null}

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

            <Card title={"Devices needing you (" + needy.length + ")"}
              note="Offline, waiting to be set up, or on a flat battery."
              actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/devices")}>All devices</Button>}>
              {needy.length ? (
                <Rows>
                  {needy.map((device) => (
                    <Row key={device.id}
                      title={<button type="button" className="hh-linkbtn" onClick={() => onNavigate("/devices/" + device.id)}>{device.name}</button>}
                      note={roomName(device.room) + " · " + (device.status === "offline" ? "last reported " + formatWhen(device.lastSeenAt, now) : device.status === "setup_pending" ? "added " + formatWhen(device.addedAt, now) : "battery flat")}>
                      <StatusBadge values={DEVICE_STATUS} value={device.status} />
                      <DeviceControl device={device} viewer={viewer} onToggle={onToggleDevice} onRun={onDeviceTransition} />
                    </Row>
                  ))}
                </Rows>
              ) : <p className="hh-footnote">Every device in the house is reporting.</p>}
            </Card>

            <Card title="Upkeep" note="What is past its date, and what is booked next."
              actions={<Button variant="outline" size="sm" onClick={() => onNavigate("/upkeep")}>All jobs</Button>}>
              <Rows>
                {overdue.map((job) => (
                  <Row key={job.id}
                    title={<button type="button" className="hh-linkbtn" onClick={() => onNavigate("/upkeep/" + job.id)}>{job.title}</button>}
                    note={job.spent ? job.device.name + " has run " + formatCount(job.ranHours) + " hours of a " + formatCount(job.lifeHours) + "-hour interval" : "Due " + formatWhen(job.dueAt, now) + " · " + formatCountdown(job.dueAt, now)}>
                    <Badge size="sm" variant="warning">{formatCountdown(job.dueAt, now)}</Badge>
                    <Transitions transitions={jobTransitions(job, viewer).filter((t) => t.primary)} onRun={(t) => onJobTransition(job, t)} />
                  </Row>
                ))}
                {nextJob ? (
                  <Row title={nextJob.title}
                    note={providerName(data.providers, nextJob.providerId) + " · " + formatWhen(nextJob.scheduledAt, now) + (nextJob.status === "in_progress" ? " — here now" : "")}
                    value={<StatusBadge values={JOB_STATUS} value={nextJob.status} />} />
                ) : null}
              </Rows>
            </Card>

            {leak ? (
              <Card title="Water" note="Water that keeps moving while the house is asleep is the only way a slow leak shows up.">
                <Rows>
                  <Row title={leak.perNight + " litres a night, " + leak.nights + " nights running"}
                    note={"Since " + formatWhen(leak.since, now) + " · " + leak.litres + " litres in total, against 4 to 6 on a normal night"}
                    value={<Badge size="sm" variant="warning">Check</Badge>} />
                </Rows>
                <div style={{ marginTop: "var(--space-3)" }}>
                  <Button variant="outline" size="sm" onClick={() => onNavigate("/energy")}>Water and energy</Button>
                </div>
              </Card>
            ) : null}

            {brokenRoutines.length ? (
              <Card title={"Routines that stopped working (" + brokenRoutines.length + ")"} note="Unfinished, or naming a device that is no longer in the house.">
                <Rows>
                  {brokenRoutines.map((routine) => (
                    <Row key={routine.id} title={routine.name}
                      note={routine.missing.length ? "Names " + routine.missing.map((id) => deviceName(data.devices, id)).join(" and ") + ", which is not in the house" : "Never finished — " + routine.note}>
                      <StatusBadge values={ROUTINE_STATUS} value={routine.status} />
                      <Button variant="outline" size="sm" onClick={() => onNavigate("/routines")}>Open</Button>
                    </Row>
                  ))}
                </Rows>
              </Card>
            ) : null}
          </div>
        </div>
      </>
    );
  }

  Object.assign(window, { TodayScreen, armTransitions, VerdictCard });
})();
