import {
  selectAppUpdateCompleted,
  selectAppUpdateProgress,
  selectAppUpdateSpeed,
  selectUpdateAvailable,
} from "@renderer/redux/app.slice";
import { useAppSelector } from "@renderer/redux/reduxHooks";
import { Affix, Button, Card, Progress } from "antd";
import { useTranslation } from "react-i18next";
import ipcTypes from "../../../../util/ipcTypes.json";

const UpdateAvailable: React.FC = () => {
  const { t } = useTranslation();
  const isUpdateAvailable = useAppSelector(selectUpdateAvailable);
  const updateSpeed = useAppSelector(selectAppUpdateSpeed);
  const updateProgress = useAppSelector(selectAppUpdateProgress);
  const isUpdateComplete = useAppSelector(selectAppUpdateCompleted);

  const handleDownload = (): void => {
    window.electron.ipcRenderer.send(ipcTypes.toMain.updates.download);
  };

  const handleApply = (): void => {
    window.electron.ipcRenderer.send(ipcTypes.toMain.updates.apply);
  };

  if (!isUpdateAvailable) {
    return null;
  }
  return (
    <Affix offsetTop={40} style={{ position: "absolute", right: 20 }}>
      <Card title={t("updates.available")} style={{ width: "33vw" }}>
        {updateProgress === 0 && (
          <Button onClick={handleDownload}>{t("updates.download")}</Button>
        )}
        <Progress
          percent={updateProgress}
          percentPosition={{ align: "center", type: "outer" }}
        />
        {formatSpeed(updateSpeed)}
        {isUpdateComplete && (
          <Button onClick={handleApply}>{t("updates.apply")}</Button>
        )}
      </Card>
    </Affix>
  );
};

export default UpdateAvailable;

/**
 * Formats bytes into a human-readable string with appropriate units
 * @param bytes Number of bytes
 * @returns Formatted string with appropriate unit (B/KB/MB/GB)
 */
const formatSpeed = (bytes: number): string => {
  if (bytes === 0) return "0 B/s";

  const units = ["B/s", "KB/s", "MB/s", "GB/s"];
  const i = Math.floor(Math.log(bytes) / Math.log(1024));

  // Limit to available units and format with 2 decimal places (rounded)
  return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${units[i] || units[units.length - 1]}`;
};
