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

export function SystemInfoWidget(): React.ReactElement {
  const [config, setConfig] = React.useState<SysInfoConfig | undefined>();

  const load = async () => {
    setConfig(await SysInfoApi.GetConfig());
  };

  return (
    <SectionContainer>
      <AsyncWidget
        loadKey={1}
        load={load}
        errMsg="Failed to check system configuration!"
        loadingMessage="Checking server configuration..."
        build={() =>
          config?.allowed ? (
            <SystemInfoWidgetInner />
          ) : (
            <SystemInfoWidgetUnavailable />
          )
        }
      />
    </SectionContainer>
  );
}

function SystemInfoWidgetUnavailable(): React.ReactElement {
  return (
    <p style={{ textAlign: "center" }}>
      Unfortunatley, system information is available. (not enough privileges)
    </p>
  );
}

function SystemInfoWidgetInner(): 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 (
    <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>
      )}
    />
  );
}

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>;
}
