import { Field, ProgressBar } from "@fluentui/react-components";
import { filesize } from "filesize";
import React from "react";
import { SysInfoApi, SysInfoStatus } from "../api/SysInfoApi";
import { useToast } from "../hooks/providers/ToastProvider";
import { format_duration } from "../utils/time_utils";
import { AsyncWidget } from "./AsyncWidget";
import { SectionContainer } from "./SectionContainer";

export function SystemInfoWidget(): React.ReactElement {
  const toast = useToast();

  const [status, setStatus] = React.useState<SysInfoStatus | undefined>();

  const load = async () => {
    setStatus(await SysInfoApi.Status());
  };

  React.useEffect(() => {
    const interval = setInterval(async () => {
      try {
        await load();
      } catch (e) {
        console.error(e);
        toast("Error", "Failed to refresh system status!", "error");
      }
    }, 5000);
    return () => clearInterval(interval);
  });

  return (
    <SectionContainer>
      <AsyncWidget
        loadKey={1}
        load={load}
        loadingMessage="Loading system status..."
        errMsg="Failed to load system status!"
        build={() => (
          <div
            style={{
              display: "flex",
              flexDirection: "row",
              alignItems: "center",
              justifyContent: "center",
            }}
          >
            <Field
              validationMessage={`${filesize(
                status!.system.used_memory
              )} of memory used out of ${filesize(
                status!.system.available_memory + status!.system.used_memory
              )}`}
              validationState="none"
              style={{ flex: 2 }}
            >
              <ProgressBar
                value={
                  status!.system.used_memory /
                  (status!.system.available_memory + status!.system.used_memory)
                }
              />
            </Field>
            <div style={{ width: "20px" }}></div>
            <div style={{ flex: 1 }}>
              <p>
                Load average: {status!.system.load_average.one}{" "}
                {status!.system.load_average.five}{" "}
                {status!.system.load_average.fifteen}
              </p>
              <UptimeWidget uptime={status!.system.uptime} />
              Number physical cores: {status!.system.physical_core_count}
            </div>
          </div>
        )}
      />
    </SectionContainer>
  );
}

function UptimeWidget(p: { uptime: number }): React.ReactElement {
  const [uptime, setUptime] = React.useState(p.uptime);

  React.useEffect(() => {
    const interval = setInterval(() => setUptime((uptime) => uptime + 1), 1000);
    return () => clearInterval(interval);
  }, [p.uptime]);

  return <p>Uptime: {format_duration(uptime)}</p>;
}
