import type {
  HassEntity,
  HassEntityAttributeBase,
  HassEntityBase,
} from "home-assistant-js-websocket";
import { createDurationData } from "../common/datetime/create_duration_data";
import durationToSeconds from "../common/datetime/duration_to_seconds";
import secondsToDuration from "../common/datetime/seconds_to_duration";
import type { HaDurationData } from "../components/ha-duration-input";
import type { HomeAssistant } from "../types";

export type TimerEntity = HassEntityBase & {
  attributes: HassEntityAttributeBase & {
    duration: string;
    remaining: string;
    restore: boolean;
  };
};

export interface DurationDict {
  hours?: number | string;
  minutes?: number | string;
  seconds?: number | string;
}

export interface Timer {
  id: string;
  name: string;
  icon?: string;
  duration?: string | number | DurationDict;
  restore?: boolean;
}

export interface TimerMutableParams {
  name: string;
  icon: string;
  duration: string | number | DurationDict;
  restore: boolean;
}

export const fetchTimer = (hass: HomeAssistant) =>
  hass.callWS<Timer[]>({ type: "timer/list" });

export const createTimer = (hass: HomeAssistant, values: TimerMutableParams) =>
  hass.callWS<Timer>({
    type: "timer/create",
    ...values,
  });

export const updateTimer = (
  hass: HomeAssistant,
  id: string,
  updates: Partial<TimerMutableParams>
) =>
  hass.callWS<Timer>({
    type: "timer/update",
    timer_id: id,
    ...updates,
  });

export const deleteTimer = (hass: HomeAssistant, id: string) =>
  hass.callWS({
    type: "timer/delete",
    timer_id: id,
  });

export const timerTimeRemaining = (
  stateObj: HassEntity
): undefined | number => {
  if (!stateObj.attributes.remaining) {
    return undefined;
  }
  let timeRemaining = durationToSeconds(stateObj.attributes.remaining);

  if (stateObj.state === "active") {
    const now = new Date().getTime();
    const finishes = new Date(stateObj.attributes.finishes_at).getTime();
    timeRemaining = Math.max((finishes - now) / 1000, 0);
  }

  return timeRemaining;
};

export const computeDisplayTimer = (
  hass: HomeAssistant,
  stateObj: HassEntity,
  timeRemaining?: number
): string | null => {
  if (!stateObj) {
    return null;
  }

  if (stateObj.state === "idle" || timeRemaining === 0) {
    return hass.formatEntityState(stateObj);
  }

  let display = secondsToDuration(timeRemaining || 0) || "0";

  if (stateObj.state === "paused") {
    display = `${display} (${hass.formatEntityState(stateObj)})`;
  }

  return display;
};

// Prefill for the duration input: always the configured duration, independent
// of the live countdown. The field is meant to be edited, not to mirror the
// remaining time.
export const timerDurationData = (
  stateObj: HassEntity
): HaDurationData | undefined =>
  createDurationData(stateObj.attributes.duration);
