/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { toFunction, GenericController } from "@arcgis/lumina/controllers";
import { createEvent } from "@arcgis/lumina";
import { l as localizedTwentyFourHourMeridiems, i as isValidNumber, n as numberStringFormatter, g as getDateTimeFormat, b as getSupportedNumberingSystem } from "./locale.js";
import { d as decimalPlaces, g as getDecimals } from "./math.js";
import { c as capitalizeWord } from "./text.js";
import { n as numberKeys } from "./key.js";
const maxTenthForMinuteAndSecond = 5;
function createLocaleDateTimeFormatter({
  locale,
  numberingSystem,
  includeSeconds,
  fractionalSecondDigits,
  hour12
}) {
  const options = {
    hour: "2-digit",
    minute: "2-digit",
    timeZone: "UTC",
    numberingSystem: getSupportedNumberingSystem(numberingSystem)
  };
  if (typeof hour12 === "boolean") {
    options.hour12 = hour12;
  }
  if (includeSeconds) {
    options.second = "2-digit";
    if (fractionalSecondDigits) {
      options.fractionalSecondDigits = fractionalSecondDigits;
    }
  }
  return getDateTimeFormat(locale, options);
}
function formatFractionalSecond(fractionalSecondAsIntegerString, step) {
  return parseFloat(`0.${fractionalSecondAsIntegerString}`).toFixed(decimalPlaces(step)).replace("0.", "");
}
function formatTimePart(number, minLength) {
  if (number === null || number === void 0) {
    return;
  }
  const numberAsString = number.toString();
  const numberDecimalPlaces = decimalPlaces(number);
  if (number < 1 && numberDecimalPlaces > 0 && numberDecimalPlaces < 4) {
    const fractionalDigits = numberAsString.replace("0.", "");
    if (!minLength || fractionalDigits.length === minLength) {
      return fractionalDigits;
    }
    if (fractionalDigits.length < minLength) {
      return fractionalDigits.padEnd(minLength, "0");
    }
    return fractionalDigits;
  }
  if (number >= 0 && number < 10) {
    return numberAsString.padStart(2, "0");
  }
  if (number >= 10) {
    return numberAsString;
  }
}
function fractionalSecondPartToMilliseconds(fractionalSecondPart) {
  return parseInt((parseFloat(`0.${fractionalSecondPart}`) / 1e-3).toFixed(3));
}
function getLocaleHourFormat(locale) {
  const options = { locale };
  if (locale === "mk") {
    options.hour12 = false;
  } else if (locale.toLowerCase() === "es-mx") {
    options.hour12 = true;
  }
  const formatter = createLocaleDateTimeFormatter(options);
  const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
  return parts.find(({ type }) => type === "dayPeriod")?.value ? "12" : "24";
}
function getLocalizedMeridiem({
  locale,
  meridiem,
  parts: fromParts
}) {
  const localesWithBrowserBugs = ["he", "bs", "mk"];
  let localizedMeridiem;
  if (fromParts) {
    localizedMeridiem = fromParts.find(({ type }) => type === "dayPeriod")?.value || null;
    if (locale && localesWithBrowserBugs.includes(locale)) {
      const localeData = localizedTwentyFourHourMeridiems.get(locale);
      if (localizedMeridiem === "PM") {
        localizedMeridiem = localeData.pm;
      }
      if (localizedMeridiem === "AM") {
        localizedMeridiem = localeData.am;
      }
    }
  } else if (meridiem) {
    if (localesWithBrowserBugs.includes(locale)) {
      const localeData = localizedTwentyFourHourMeridiems.get(locale);
      localizedMeridiem = meridiem === "PM" ? localeData.pm : localeData.am;
    } else {
      const formatter = createLocaleDateTimeFormatter({ locale, hour12: true });
      const arbitraryAMHour = 6;
      const arbitraryPMHour = 18;
      const dateWithHourBasedOnMeridiem = new Date(
        Date.UTC(0, 0, 0, meridiem === "AM" ? arbitraryAMHour : arbitraryPMHour, 0)
      );
      const parts = formatter.formatToParts(dateWithHourBasedOnMeridiem);
      localizedMeridiem = parts.find(({ type }) => type === "dayPeriod")?.value || null;
    }
  }
  return localizedMeridiem;
}
function getLocalizedDecimalSeparator(locale, numberingSystem) {
  numberStringFormatter.numberFormatOptions = {
    locale,
    numberingSystem
  };
  return numberStringFormatter.localize("1.1").split("")[1];
}
function getLocalizedTimePartSuffix({
  hour12,
  locale,
  numberingSystem = "latn",
  part,
  step
}) {
  const formatter = createLocaleDateTimeFormatter({ hour12, includeSeconds: step < 60, locale, numberingSystem });
  const parts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0, 0)));
  return getLocalizedTimePart(`${part}Suffix`, parts, locale);
}
function getLocalizedTimePart(part, parts, locale = "en") {
  if (!part || !parts) {
    return null;
  }
  if (part === "hourSuffix") {
    const hourPart = parts.find(({ type }) => type === "hour");
    const minutePart = parts.find(({ type }) => type === "minute");
    const hourIndex = hourPart ? parts.indexOf(hourPart) : -1;
    const minuteIndex = minutePart ? parts.indexOf(minutePart) : -1;
    const hourSuffix = parts[hourIndex + 1];
    return hourSuffix?.type === "literal" && minuteIndex - hourIndex === 2 ? hourSuffix.value || null : null;
  }
  if (part === "minuteSuffix") {
    const minutePart = parts.find(({ type }) => type === "minute");
    const minuteIndex = minutePart ? parts.indexOf(minutePart) : -1;
    const minuteSuffix = parts[minuteIndex + 1];
    return minuteSuffix?.type === "literal" ? minuteSuffix.value || null : null;
  }
  if (part === "secondSuffix") {
    let secondSuffixPart;
    const fractionalSecondPart = parts.find(({ type }) => type === "fractionalSecond");
    const fractionalSecondIndex = fractionalSecondPart ? parts.indexOf(fractionalSecondPart) : -1;
    if (fractionalSecondIndex !== -1) {
      secondSuffixPart = parts[fractionalSecondIndex + 1];
    } else {
      const secondPart = parts.find(({ type }) => type === "second");
      const secondIndex = secondPart ? parts.indexOf(secondPart) : -1;
      secondSuffixPart = parts[secondIndex + 1];
    }
    return secondSuffixPart?.type === "literal" && secondSuffixPart.value || null;
  }
  if (part === "meridiem") {
    const meridiemFromBrowser = parts.find(({ type }) => type === "dayPeriod")?.value || null;
    if (meridiemFromBrowser) {
      return getLocalizedMeridiem({ locale, parts }) ?? null;
    }
  }
  return parts.find(({ type }) => type === part)?.value || null;
}
function getMeridiem(hour) {
  if (!isValidNumber(hour)) {
    return null;
  }
  const hourAsNumber = parseInt(hour);
  return hourAsNumber >= 0 && hourAsNumber <= 11 ? "AM" : "PM";
}
function getMeridiemOrder(locale) {
  const formatter = new Intl.DateTimeFormat(locale, {
    hour: "2-digit",
    hour12: true,
    minute: "2-digit",
    timeZone: "UTC"
  });
  const timeParts = formatter.formatToParts(new Date(Date.UTC(0, 0, 0, 0, 0)));
  return timeParts.findIndex((value) => value.type === "dayPeriod");
}
function isValidTime(value) {
  const isString = typeof value === "string";
  if (!value || isString && (value.startsWith(":") || value.endsWith(":")) || !isString && (!value.hour || !value.minute)) {
    return false;
  }
  let hour;
  let minute;
  let second;
  if (isString) {
    [hour, minute, second] = value.split(":");
  } else {
    ({ hour, minute, second } = value);
  }
  if (!hour || !minute) {
    return false;
  }
  const hourAsNumber = parseInt(hour);
  const minuteAsNumber = parseInt(minute);
  const secondAsNumber = parseInt(second ?? "");
  const hourValid = isValidNumber(hour) && hourAsNumber >= 0 && hourAsNumber < 24;
  const minuteValid = isValidNumber(minute) && minuteAsNumber >= 0 && minuteAsNumber < 60;
  const secondValid = isValidNumber(second) && secondAsNumber >= 0 && secondAsNumber < 60;
  return hourValid && minuteValid && (!second || secondValid);
}
function isValidTimePart(value, part) {
  if (part === "meridiem") {
    return value === "AM" || value === "PM";
  }
  if (!isValidNumber(value)) {
    return false;
  }
  const valueAsString = value;
  const valueAsNumber = Number(valueAsString);
  const isZeroOrGreater = valueAsNumber >= 0;
  const isLessThanMaxHour = valueAsNumber < 24;
  const isLessThanMaxSecond = valueAsNumber < 60;
  const isLessThanMaxFractionalSecond = valueAsNumber <= 999;
  if (part === "hour") {
    return isZeroOrGreater && isLessThanMaxHour;
  }
  if (part === "fractionalSecond") {
    return isZeroOrGreater && isLessThanMaxFractionalSecond;
  }
  return isZeroOrGreater && isLessThanMaxSecond;
}
function localizeTimePart({
  value,
  part,
  locale,
  numberingSystem = "latn",
  hour12
}) {
  if (!isValidTimePart(value, part)) {
    return;
  }
  if (part === "fractionalSecond") {
    const localizedDecimalSeparator = getLocalizedDecimalSeparator(locale, numberingSystem);
    let localizedFractionalSecond = null;
    if (value) {
      numberStringFormatter.numberFormatOptions = {
        locale,
        numberingSystem
      };
      const localizedZero = numberStringFormatter.localize("0");
      if (parseInt(value) === 0) {
        localizedFractionalSecond = "".padStart(value.length, localizedZero);
      } else {
        localizedFractionalSecond = numberStringFormatter.localize(`0.${value}`).replace(`${localizedZero}${localizedDecimalSeparator}`, "");
        if (localizedFractionalSecond.length < value.length) {
          localizedFractionalSecond = localizedFractionalSecond.padEnd(value.length, localizedZero);
        }
      }
    }
    return localizedFractionalSecond;
  }
  const valueAsNumber = parseInt(value);
  const date = new Date(
    Date.UTC(
      0,
      0,
      0,
      part === "hour" ? valueAsNumber : part === "meridiem" ? value === "AM" ? 0 : 12 : 0,
      part === "minute" ? valueAsNumber : 0,
      part === "second" ? valueAsNumber : 0
    )
  );
  if (!date) {
    return;
  }
  const includeSeconds = ["second", "fractionalSecond"].includes(part);
  const formatter = createLocaleDateTimeFormatter({ hour12, includeSeconds, locale, numberingSystem });
  const parts = formatter.formatToParts(date);
  return getLocalizedTimePart(part, parts, locale);
}
function localizeTimeString({
  hour12,
  locale,
  numberingSystem = "latn",
  parts: toParts = false,
  step,
  value
}) {
  if (!isValidTime(value)) {
    return null;
  }
  const { hour, minute, second = "0", fractionalSecond } = parseTimeString(value, step);
  const includeSeconds = step < 60;
  const dateFromTimeString = new Date(
    Date.UTC(
      0,
      0,
      0,
      parseInt(hour),
      parseInt(minute),
      includeSeconds && typeof second === "string" ? parseInt(second) : 0,
      includeSeconds && fractionalSecond ? fractionalSecondPartToMilliseconds(fractionalSecond) : 0
    )
  );
  const formatter = createLocaleDateTimeFormatter({
    fractionalSecondDigits: decimalPlaces(step),
    hour12,
    includeSeconds,
    locale,
    numberingSystem
  });
  if (toParts) {
    const parts = formatter.formatToParts(dateFromTimeString);
    return {
      hour: getLocalizedTimePart("hour", parts),
      hourSuffix: getLocalizedTimePart("hourSuffix", parts),
      minute: getLocalizedTimePart("minute", parts),
      minuteSuffix: getLocalizedTimePart("minuteSuffix", parts),
      second: getLocalizedTimePart("second", parts),
      decimalSeparator: getLocalizedDecimalSeparator(locale, numberingSystem),
      fractionalSecond: getLocalizedTimePart("fractionalSecond", parts),
      secondSuffix: locale !== "bg" ? getLocalizedTimePart("secondSuffix", parts) : null,
      meridiem: getLocalizedTimePart("meridiem", parts, locale)
    };
  } else {
    let result = formatter.format(dateFromTimeString) || null;
    if (!toParts && typeof result === "string" && locale === "bg" && result && result.includes(" ч.")) {
      result = result.replaceAll(" ч.", "");
    }
    if (["he", "bs", "mk"].includes(locale)) {
      const localeData = localizedTwentyFourHourMeridiems.get(locale);
      if (result.includes("AM")) {
        result = result.replaceAll("AM", localeData.am);
      } else if (result.includes("PM")) {
        result = result.replaceAll("PM", localeData.pm);
      }
      if (locale !== "he" && result.indexOf(".") !== result.length - 1) {
        result = result.replace(".", ",");
      }
    }
    return result;
  }
}
function parseTimeString(value, step) {
  if (isValidTime(value)) {
    const [hour, minute, secondDecimal] = value.split(":");
    let second = secondDecimal;
    let fractionalSecond = null;
    if (secondDecimal?.includes(".")) {
      [second, fractionalSecond] = secondDecimal.split(".");
    }
    if (step && typeof fractionalSecond === "string") {
      fractionalSecond = formatFractionalSecond(fractionalSecond, step);
    }
    return {
      fractionalSecond,
      hour,
      minute,
      second
    };
  }
  return {
    fractionalSecond: null,
    hour: null,
    minute: null,
    second: null
  };
}
function toISOTimeString(value, step = 60) {
  if (!isValidTime(value)) {
    return null;
  }
  let hour;
  let minute;
  let second;
  let secondDecimal;
  let fractionalSecond;
  let isoTimeString = null;
  if (typeof value === "string") {
    [hour, minute, secondDecimal] = value.split(":");
    [second, fractionalSecond] = secondDecimal?.split(".") || ["0"];
  } else {
    hour = value.hour;
    minute = value.minute;
    second = value.second;
    fractionalSecond = value.fractionalSecond;
  }
  if (hour && minute) {
    isoTimeString = `${formatTimePart(parseInt(hour))}:${formatTimePart(parseInt(minute))}`;
    if (step < 60) {
      isoTimeString += `:${formatTimePart(parseInt(second || "0"))}`;
      if (step < 1) {
        isoTimeString += `.${formatFractionalSecond(fractionalSecond || "0", step)}`;
      }
    }
  }
  return isoTimeString;
}
class TimeController extends GenericController {
  constructor() {
    super(...arguments);
    this.localizedDecimalSeparator = ".";
    this.userChangedValue = false;
    this.handleHourKeyDownEvent = (event) => {
      const key = event.key;
      if (numberKeys.includes(key)) {
        const keyAsNumber = parseInt(key);
        let newHour;
        if (isValidNumber(this.hour)) {
          switch (this.hourFormat) {
            case "12":
              newHour = this.hour === "01" && keyAsNumber >= 0 && keyAsNumber <= 2 ? `1${keyAsNumber}` : keyAsNumber;
              break;
            case "24":
              if (this.hour === "01") {
                newHour = `1${keyAsNumber}`;
              } else if (this.hour === "02" && keyAsNumber >= 0 && keyAsNumber <= 3) {
                newHour = `2${keyAsNumber}`;
              } else {
                newHour = keyAsNumber;
              }
              break;
          }
        } else {
          newHour = keyAsNumber;
        }
        this.setValuePart("hour", newHour);
      } else {
        switch (key) {
          case "Backspace":
          case "Delete":
            event.preventDefault();
            this.setValuePart("hour", void 0);
            break;
          case "ArrowDown":
            event.preventDefault();
            this.decrementHour();
            break;
          case "ArrowUp":
            event.preventDefault();
            this.incrementHour();
            break;
          case " ":
          case "Spacebar":
            event.preventDefault();
            break;
        }
      }
    };
    this.handleMinuteKeyDownEvent = (event) => {
      const key = event.key;
      if (numberKeys.includes(key)) {
        const keyAsNumber = parseInt(key);
        let newMinute;
        if (typeof this.minute === "string" && isValidNumber(this.minute) && this.minute.startsWith("0")) {
          const minuteAsNumber = parseInt(this.minute);
          newMinute = minuteAsNumber > maxTenthForMinuteAndSecond ? keyAsNumber : `${minuteAsNumber}${keyAsNumber}`;
        } else {
          newMinute = keyAsNumber;
        }
        this.setValuePart("minute", newMinute);
      } else {
        switch (key) {
          case "Backspace":
          case "Delete":
            event.preventDefault();
            this.setValuePart("minute", void 0);
            break;
          case "ArrowDown":
            event.preventDefault();
            this.decrementMinute();
            break;
          case "ArrowUp":
            event.preventDefault();
            this.incrementMinute();
            break;
          case " ":
          case "Spacebar":
            event.preventDefault();
            break;
        }
      }
    };
    this.handleSecondKeyDownEvent = (event) => {
      const key = event.key;
      if (numberKeys.includes(key)) {
        const keyAsNumber = parseInt(key);
        let newSecond;
        if (typeof this.second === "string" && isValidNumber(this.second) && this.second.startsWith("0")) {
          const secondAsNumber = parseInt(this.second);
          newSecond = secondAsNumber > maxTenthForMinuteAndSecond ? keyAsNumber : `${secondAsNumber}${keyAsNumber}`;
        } else {
          newSecond = keyAsNumber;
        }
        this.setValuePart("second", newSecond);
      } else {
        switch (key) {
          case "Backspace":
          case "Delete":
            event.preventDefault();
            this.setValuePart("second", void 0);
            break;
          case "ArrowDown":
            event.preventDefault();
            this.decrementSecond();
            break;
          case "ArrowUp":
            event.preventDefault();
            this.incrementSecond();
            break;
          case " ":
          case "Spacebar":
            event.preventDefault();
            break;
        }
      }
    };
    this.handleFractionalSecondKeyDownEvent = (event) => {
      const { key } = event;
      if (numberKeys.includes(key)) {
        const stepPrecision = decimalPlaces(this.component.step);
        const fractionalSecondAsInteger = parseInt(this.fractionalSecond);
        const fractionalSecondAsIntegerLength = fractionalSecondAsInteger.toString().length;
        let newFractionalSecondAsIntegerString;
        if (fractionalSecondAsIntegerLength >= stepPrecision) {
          newFractionalSecondAsIntegerString = key.padStart(stepPrecision, "0");
        } else if (fractionalSecondAsIntegerLength < stepPrecision) {
          newFractionalSecondAsIntegerString = `${fractionalSecondAsInteger}${key}`.padStart(stepPrecision, "0");
        }
        this.setValuePart("fractionalSecond", parseFloat(`0.${newFractionalSecondAsIntegerString}`));
      } else {
        switch (key) {
          case "Backspace":
          case "Delete":
            event.preventDefault();
            this.setValuePart("fractionalSecond", void 0);
            break;
          case "ArrowDown":
            event.preventDefault();
            this.nudgeFractionalSecond("down");
            break;
          case "ArrowUp":
            event.preventDefault();
            this.nudgeFractionalSecond("up");
            break;
          case " ":
            event.preventDefault();
            break;
        }
      }
    };
    this.handleMeridiemKeyDownEvent = (event) => {
      switch (event.key) {
        case "a":
          this.setValuePart("meridiem", "AM");
          break;
        case "p":
          this.setValuePart("meridiem", "PM");
          break;
        case "Backspace":
        case "Delete":
          event.preventDefault();
          this.setValuePart("meridiem");
          break;
        case "ArrowUp":
          event.preventDefault();
          this.toggleMeridiem("up");
          break;
        case "ArrowDown":
          event.preventDefault();
          this.toggleMeridiem("down");
          break;
        case " ":
        case "Spacebar":
          event.preventDefault();
          break;
      }
    };
    this.calciteTimeChange = createEvent();
  }
  //#endregion
  //#region Public Methods
  decrementHour() {
    const newHour = !this.hour ? 0 : this.hour === "00" ? 23 : parseInt(this.hour) - 1;
    this.setValuePart("hour", newHour);
  }
  decrementMinute() {
    this.decrementMinuteOrSecond("minute");
  }
  decrementSecond() {
    this.decrementMinuteOrSecond("second");
  }
  incrementHour() {
    const newHour = typeof this.hour === "string" && isValidNumber(this.hour) ? this.hour === "23" ? 0 : parseInt(this.hour) + 1 : 1;
    this.setValuePart("hour", newHour);
  }
  incrementMinute() {
    this.incrementMinuteOrSecond("minute");
  }
  incrementSecond() {
    this.incrementMinuteOrSecond("second");
  }
  nudgeFractionalSecond(direction) {
    const stepDecimal = getDecimals(this.component.step);
    const stepPrecision = decimalPlaces(this.component.step);
    const fractionalSecondAsInteger = parseInt(this.fractionalSecond);
    const fractionalSecondAsFloat = parseFloat(`0.${this.fractionalSecond}`);
    let nudgedValue;
    let nudgedValueRounded;
    let nudgedValueRoundedDecimals;
    let newFractionalSecond;
    if (direction === "up") {
      nudgedValue = isNaN(fractionalSecondAsInteger) ? 0 : fractionalSecondAsFloat + stepDecimal;
      nudgedValueRounded = parseFloat(nudgedValue.toFixed(stepPrecision));
      nudgedValueRoundedDecimals = getDecimals(nudgedValueRounded);
      newFractionalSecond = nudgedValueRounded < 1 && decimalPlaces(nudgedValueRoundedDecimals) > 0 ? formatTimePart(nudgedValueRoundedDecimals, stepPrecision) : "".padStart(stepPrecision, "0");
    }
    if (direction === "down") {
      nudgedValue = isNaN(fractionalSecondAsInteger) || fractionalSecondAsInteger === 0 ? 1 - stepDecimal : fractionalSecondAsFloat - stepDecimal;
      nudgedValueRounded = parseFloat(nudgedValue.toFixed(stepPrecision));
      nudgedValueRoundedDecimals = getDecimals(nudgedValueRounded);
      newFractionalSecond = nudgedValueRounded < 1 && decimalPlaces(nudgedValueRoundedDecimals) > 0 && Math.sign(nudgedValueRoundedDecimals) === 1 ? formatTimePart(nudgedValueRoundedDecimals, stepPrecision) : "".padStart(stepPrecision, "0");
    }
    this.setValuePart("fractionalSecond", newFractionalSecond);
  }
  toggleMeridiem(direction) {
    let newMeridiem;
    if (!this.meridiem) {
      newMeridiem = direction === "down" ? "PM" : "AM";
    } else {
      newMeridiem = this.meridiem === "AM" ? "PM" : "AM";
    }
    this.setValuePart("meridiem", newMeridiem);
  }
  //#endregion
  //#region Private Methods
  hostConnected() {
    this.setHourFormat();
    this.setMeridiemOrder();
    this.setValue(this.component.value);
  }
  hostUpdate(changes) {
    let updateHourFormat = false;
    let updateMeridiemOrder = false;
    let updateValue = false;
    if (changes.has("hourFormat")) {
      updateHourFormat = true;
      updateValue = true;
    }
    if (changes.has("messages") && changes.get("messages")?._lang !== this.component.messages._lang) {
      updateHourFormat = true;
      updateMeridiemOrder = true;
      updateValue = true;
    }
    if (changes.has("numberingSystem")) {
      updateValue = true;
    }
    if (changes.has("step")) {
      const oldStep = this.component.step;
      const newStep = changes.get("step");
      if (oldStep >= 60 && newStep > 0 && newStep < 60 || newStep >= 60 && oldStep > 0 && oldStep < 60) {
        updateValue = true;
      }
    }
    if (updateHourFormat) {
      this.setHourFormat();
    }
    if (updateMeridiemOrder) {
      this.setMeridiemOrder();
    }
    if (updateValue) {
      this.setValue(this.component.value);
    }
    this.userChangedValue = false;
  }
  decrementMinuteOrSecond(key) {
    let newValue;
    if (isValidNumber(this[key])) {
      const valueAsNumber = parseInt(this[key]);
      newValue = valueAsNumber === 0 ? 59 : valueAsNumber - 1;
    } else {
      newValue = 59;
    }
    this.setValuePart(key, newValue);
  }
  incrementMinuteOrSecond(key) {
    const newValue = isValidNumber(this[key]) ? this[key] === "59" ? 0 : parseInt(this[key]) + 1 : 0;
    this.setValuePart(key, newValue);
  }
  setHourFormat() {
    const { hourFormat, messages } = this.component;
    this.hourFormat = hourFormat === "user" ? getLocaleHourFormat(messages._lang) : hourFormat;
  }
  setMeridiemOrder() {
    const { messages } = this.component;
    this.meridiemOrder = getMeridiemOrder(messages._lang);
  }
  setValue(value, userChangedValue = false) {
    const { messages, numberingSystem, step, value: previousValue } = this.component;
    const locale = messages._lang;
    const hour12 = this.hourFormat === "12";
    const newValue = toISOTimeString(value, step);
    if (isValidTime(value)) {
      const { hour, minute, second, fractionalSecond } = parseTimeString(newValue, step);
      const localized = localizeTimeString({
        hour12,
        locale,
        numberingSystem,
        parts: true,
        step,
        value: newValue
      });
      this.hour = hour;
      this.minute = minute;
      this.second = second;
      this.fractionalSecond = fractionalSecond;
      if (localized) {
        this.localizedHour = localized.hour;
        this.localizedHourSuffix = localized.hourSuffix;
        this.localizedMinute = localized.minute;
        this.localizedMinuteSuffix = localized.minuteSuffix;
        this.localizedSecond = localized.second;
        this.localizedDecimalSeparator = localized.decimalSeparator;
        this.localizedFractionalSecond = localized.fractionalSecond;
        this.localizedSecondSuffix = localized.secondSuffix;
        if (localized.meridiem) {
          this.meridiem = getMeridiem(this.hour);
          this.localizedMeridiem = localized.meridiem;
        }
      }
    } else {
      this.hour = null;
      this.minute = null;
      this.second = null;
      this.fractionalSecond = null;
      this.meridiem = null;
      this.localizedHour = null;
      this.localizedHourSuffix = getLocalizedTimePartSuffix({ hour12, part: "hour", locale, numberingSystem, step });
      this.localizedMinute = null;
      this.localizedMinuteSuffix = getLocalizedTimePartSuffix({
        hour12,
        part: "minute",
        locale,
        numberingSystem,
        step
      });
      this.localizedSecond = null;
      this.localizedDecimalSeparator = getLocalizedDecimalSeparator(locale, numberingSystem);
      this.localizedFractionalSecond = null;
      this.localizedSecondSuffix = getLocalizedTimePartSuffix({
        hour12,
        part: "second",
        locale,
        numberingSystem,
        step
      });
      this.localizedMeridiem = null;
    }
    if (newValue !== previousValue) {
      this.userChangedValue = userChangedValue;
      this.component.value = newValue ?? "";
    } else {
      this.component.requestUpdate();
    }
  }
  setValuePart(key, value) {
    const { hourFormat } = this;
    const { messages, numberingSystem, step } = this.component;
    const locale = messages._lang;
    const hour12 = hourFormat === "12";
    const previousValue = this.component.value;
    if (key === "meridiem") {
      const oldMeridiem = this.meridiem;
      this.meridiem = value;
      this.localizedMeridiem = localizeTimePart({
        hour12,
        locale,
        numberingSystem,
        part: "meridiem",
        value: this.meridiem
      });
      if (isValidNumber(this.hour)) {
        const hourAsNumber = parseInt(this.hour);
        switch (value) {
          case "AM":
            if (hourAsNumber >= 12) {
              this.hour = formatTimePart(hourAsNumber - 12);
            }
            break;
          case "PM":
            if (hourAsNumber < 12) {
              this.hour = formatTimePart(hourAsNumber + 12);
            }
            break;
          default:
            this.userChangedValue = true;
            this.component.value = "";
            break;
        }
        this.localizedHour = localizeTimePart({
          hour12,
          locale,
          numberingSystem,
          part: "hour",
          value: this.hour
        });
      }
      if (oldMeridiem !== this.meridiem) {
        this.component.requestUpdate();
      }
    } else if (key === "fractionalSecond") {
      const oldFractionalSecond = this.fractionalSecond;
      const stepPrecision = decimalPlaces(step);
      if (typeof value === "number") {
        this.fractionalSecond = value === 0 ? "".padStart(stepPrecision, "0") : formatTimePart(value, stepPrecision);
      } else {
        this.fractionalSecond = value;
      }
      this.localizedFractionalSecond = localizeTimePart({
        value: this.fractionalSecond,
        part: "fractionalSecond",
        locale,
        numberingSystem,
        hour12
      });
      if (oldFractionalSecond !== this.fractionalSecond) {
        this.component.requestUpdate();
      }
    } else {
      const oldValue = this[key];
      this[key] = typeof value === "number" ? formatTimePart(value) : value;
      this[`localized${capitalizeWord(key)}`] = localizeTimePart({
        value: this[key],
        part: key,
        locale,
        numberingSystem,
        hour12
      });
      if (oldValue !== this[key]) {
        this.component.requestUpdate();
      }
    }
    const { hour, minute, second, fractionalSecond } = this;
    const newValue = toISOTimeString({ hour, minute, second, fractionalSecond }, step);
    if (previousValue !== newValue) {
      if (key === "hour" && hourFormat === "12") {
        this.meridiem = getMeridiem(hour);
        this.localizedMeridiem = getLocalizedMeridiem({ locale, meridiem: this.meridiem });
      }
      this.userChangedValue = true;
      this.calciteTimeChange.emit(newValue ?? "");
    }
  }
  //#endregion
}
const useTime = toFunction(TimeController);
export {
  useTime as u
};
