import {
  Battery20,
  Battery30,
  Battery50,
  Battery60,
  Battery80,
  Battery90,
  BatteryAlert,
  BatteryCharging20,
  BatteryCharging30,
  BatteryCharging50,
  BatteryCharging60,
  BatteryCharging80,
  BatteryCharging90,
  BatteryChargingFull,
  BatteryFull,
  BatteryUnknown,
  PowerOff,
  Power
} from "@mui/icons-material";
import { pond } from "protobuf-ts/pond";
import { quack } from "protobuf-ts/quack";

export interface PowerDescriber {
  description: string;
  icon: any;
}

interface batteryThreshold {
  threshold: number;
  icon: any;
}

let chargingThresholds: batteryThreshold[] = [
  { threshold: 100, icon: <BatteryChargingFull style={{ color: "var(--status-ok)" }} /> },
  { threshold: 90, icon: <BatteryCharging90 style={{ color: "var(--status-ok)" }} /> },
  { threshold: 80, icon: <BatteryCharging80 style={{ color: "var(--status-ok)" }} /> },
  { threshold: 60, icon: <BatteryCharging60 style={{ color: "var(--status-unstable)" }} /> },
  { threshold: 40, icon: <BatteryCharging50 style={{ color: "var(--status-unstable)" }} /> },
  { threshold: 30, icon: <BatteryCharging30 style={{ color: "var(--status-warning)" }} /> },
  { threshold: 20, icon: <BatteryCharging20 style={{ color: "var(--status-warning)" }} /> },
  { threshold: 1, icon: <BatteryCharging20 style={{ color: "var(--status-alert)" }} /> },
  { threshold: 0, icon: <BatteryAlert style={{ color: "var(--status-alert)" }} /> }
];

let notChargingThresholds: batteryThreshold[] = [
  { threshold: 100, icon: <BatteryFull style={{ color: "var(--status-ok)" }} /> },
  { threshold: 90, icon: <Battery90 style={{ color: "var(--status-ok)" }} /> },
  { threshold: 80, icon: <Battery80 style={{ color: "var(--status-ok)" }} /> },
  { threshold: 60, icon: <Battery60 style={{ color: "var(--status-unstable)" }} /> },
  { threshold: 40, icon: <Battery50 style={{ color: "var(--status-unstable)" }} /> },
  { threshold: 30, icon: <Battery30 style={{ color: "var(--status-warning)" }} /> },
  { threshold: 20, icon: <Battery20 style={{ color: "var(--status-warning)" }} /> },
  { threshold: 1, icon: <Battery20 style={{ color: "var(--status-alert)" }} /> },
  { threshold: 0, icon: <BatteryAlert style={{ color: "var(--status-alert)" }} /> }
];

export function describePower(power?: pond.DevicePower | null): PowerDescriber {
  let result = {
    description: "",
    icon: <BatteryUnknown style={{ color: "var(--status-unknown)" }} />
  };
  if (!power) return result;
  if (power.type === quack.PowerSubtype.POWER_SUBTYPE_NO_BATTERY) {
    if (power.inputVoltage > 0) {
      result.icon = <Power style={{ color: "var(--status-ok)" }} />;
      result.description = "Plugged in";
    } else {
      result.icon = <PowerOff style={{ color: "var(--status-alert)" }} />;
      result.description = "Unplugged";
    }
  } else {
    let thresholds = notChargingThresholds;
    let suffix = "not charging";
    if (power.inputVoltage >= 4) {
      thresholds = chargingThresholds;
      if (power.chargePercent === 100) {
        suffix = "charged";
      } else {
        suffix = "charging";
      }
    }
    result.description = power.chargePercent.toString() + "%, " + suffix;
    for (let i = 0; i < thresholds.length; i++) {
      if (power.chargePercent >= thresholds[i].threshold) {
        result.icon = thresholds[i].icon;
        break;
      }
    }
  }
  return result;
}

//returns a boolean indicating whether the search term matches a power query
export function filterByPower(searchValue: string, power: pond.DevicePower | undefined): boolean {
  let matches: string[] = [];

  if (power) {
    switch (power.type) {
      case quack.PowerSubtype.POWER_SUBTYPE_NO_BATTERY:
        if (power.inputVoltage > 0) {
          matches.push("on");
        } else {
          matches.push("off");
        }
        break;
      default:
        const isCharging = power.inputVoltage >= 4.0;
        if (isCharging) {
          matches.push("charging");
        }

        if (power.chargePercent >= 0 && power.chargePercent <= 33) {
          matches.push("low");
        } else if (power.chargePercent <= 66) {
          matches.push("medium");
        } else {
          matches.push("high");
        }

        break;
    }
  } else {
    matches = ["unknown", "?"];
  }

  return matches.some(match => match.indexOf(searchValue.replace("power:", "").trim()) > -1);
}
