/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#pragma once

#include <react/debug/react_native_expect.h>
#include <react/renderer/components/iostextinput/primitives.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>

namespace facebook::react {

static TextInputTraits convertRawProp(
    const PropsParserContext& context,
    const RawProps& rawProps,
    const TextInputTraits& sourceTraits,
    const TextInputTraits& defaultTraits) {
  auto traits = TextInputTraits{};

  traits.autocapitalizationType = convertRawProp(
      context,
      rawProps,
      "autoCapitalize",
      sourceTraits.autocapitalizationType,
      defaultTraits.autocapitalizationType);
  traits.autoCorrect = convertRawProp(
      context,
      rawProps,
      "autoCorrect",
      sourceTraits.autoCorrect,
      defaultTraits.autoCorrect);
  traits.contextMenuHidden = convertRawProp(
      context,
      rawProps,
      "contextMenuHidden",
      sourceTraits.contextMenuHidden,
      defaultTraits.contextMenuHidden);
  traits.editable = convertRawProp(
      context,
      rawProps,
      "editable",
      sourceTraits.editable,
      defaultTraits.editable);
  traits.enablesReturnKeyAutomatically = convertRawProp(
      context,
      rawProps,
      "enablesReturnKeyAutomatically",
      sourceTraits.enablesReturnKeyAutomatically,
      defaultTraits.enablesReturnKeyAutomatically);
  traits.keyboardAppearance = convertRawProp(
      context,
      rawProps,
      "keyboardAppearance",
      sourceTraits.keyboardAppearance,
      defaultTraits.keyboardAppearance);
  traits.spellCheck = convertRawProp(
      context,
      rawProps,
      "spellCheck",
      sourceTraits.spellCheck,
      defaultTraits.spellCheck);
  traits.caretHidden = convertRawProp(
      context,
      rawProps,
      "caretHidden",
      sourceTraits.caretHidden,
      defaultTraits.caretHidden);
  traits.clearButtonMode = convertRawProp(
      context,
      rawProps,
      "clearButtonMode",
      sourceTraits.clearButtonMode,
      defaultTraits.clearButtonMode);
  traits.scrollEnabled = convertRawProp(
      context,
      rawProps,
      "scrollEnabled",
      sourceTraits.scrollEnabled,
      defaultTraits.scrollEnabled);
  traits.secureTextEntry = convertRawProp(
      context,
      rawProps,
      "secureTextEntry",
      sourceTraits.secureTextEntry,
      defaultTraits.secureTextEntry);
  traits.clearTextOnFocus = convertRawProp(
      context,
      rawProps,
      "clearTextOnFocus",
      sourceTraits.clearTextOnFocus,
      defaultTraits.clearTextOnFocus);
  traits.keyboardType = convertRawProp(
      context,
      rawProps,
      "keyboardType",
      sourceTraits.keyboardType,
      defaultTraits.keyboardType);
  traits.showSoftInputOnFocus = convertRawProp(
      context,
      rawProps,
      "showSoftInputOnFocus",
      sourceTraits.showSoftInputOnFocus,
      defaultTraits.showSoftInputOnFocus);
  traits.returnKeyType = convertRawProp(
      context,
      rawProps,
      "returnKeyType",
      sourceTraits.returnKeyType,
      defaultTraits.returnKeyType);
  traits.selectTextOnFocus = convertRawProp(
      context,
      rawProps,
      "selectTextOnFocus",
      sourceTraits.selectTextOnFocus,
      defaultTraits.selectTextOnFocus);
  traits.textContentType = convertRawProp(
      context,
      rawProps,
      "textContentType",
      sourceTraits.textContentType,
      defaultTraits.textContentType);
  traits.passwordRules = convertRawProp(
      context,
      rawProps,
      "passwordRules",
      sourceTraits.passwordRules,
      defaultTraits.passwordRules);
  traits.smartInsertDelete = convertRawProp(
      context,
      rawProps,
      "smartInsertDelete",
      sourceTraits.smartInsertDelete,
      defaultTraits.smartInsertDelete);

  return traits;
}

inline void fromRawValue(
    const PropsParserContext& context,
    const RawValue& value,
    Selection& result) {
  if (value.hasType<std::unordered_map<std::string, int>>()) {
    auto map = (std::unordered_map<std::string, int>)value;
    for (const auto& pair : map) {
      if (pair.first == "start") {
        result.start = pair.second;
      } else if (pair.first == "end") {
        result.end = pair.second;
      } else {
        LOG(ERROR) << "Unsupported Selection map key: " << pair.first;
        react_native_expect(false);
      }
    }
    return;
  }

  react_native_expect(value.hasType<std::vector<int>>());
  if (value.hasType<std::vector<int>>()) {
    auto array = (std::vector<int>)value;
    react_native_expect(array.size() == 2);
    if (array.size() >= 2) {
      result = {array.at(0), array.at(1)};
    } else {
      result = {0, 0};
      LOG(ERROR) << "Unsupported Selection vector size: " << array.size();
    }
  } else {
    LOG(ERROR) << "Unsupported Selection type";
  }
}
} // namespace facebook::react
