import { underscoreToPascalCase } from "./form";
import {
  BenPascalCase,
  StringCaser,
} from "@/components/WebExportReact/src/utils/helpers";
import { generateComponentId, generateComponentId2 } from "./helpers";

export function findDropDownComponents(data, result = []) {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if ("components" in item) {
      findDropDownComponents(item.components, result);
    }
    if ("children" in item) {
      findDropDownComponents(item.children, result);
    }
    if (item.name === "DropDown") {
      result.push(item);
    }
  }

  return result;
}

export function findDropDownComponent(data) {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if (item.name === "DropDown") {
      const id = generateComponentId2(item);
      return id;
    }
    if ("components" in item) {
      const result = findDropDownComponent(item.components);
      if (result) return result;
    }
    if ("children" in item) {
      const result = findDropDownComponent(item.children);
      if (result) return result;
    }
  }
  return null; // Return null if no DropDown component is found
}

function findComponentsWithSourceProp(data, result = []) {
  if (!Array.isArray(data)) data = [data];

  for (const item of data) {
    if ("components" in item) {
      findComponentsWithSourceProp(item.components, result);
    }
    if ("children" in item) {
      findComponentsWithSourceProp(item.children, result);
    }
    if (
      "props" in item &&
      item.props.source !== undefined &&
      item.props.source !== ""
    ) {
      result.push(item.props.source);
    }
  }
  return result;
}

function findComponentsWithActionProp(data, result = []) {
  if (!Array.isArray(data)) data = [data];

  for (const item of data) {
    if ("components" in item) {
      findComponentsWithActionProp(item.components, result);
    }
    if ("children" in item) {
      findComponentsWithActionProp(item.children, result);
    }
    if (
      "props" in item &&
      item.props.action !== undefined &&
      item.props.action !== ""
    ) {
      result.push(item.props.action);
    }
  }

  return result;
}

const getFields = (api, result = {}) => {
  let fields = api?.inputs;

  let newField = [];
  let allField = [];

  fields?.forEach((field) => {
    let formatedField = underscoreToPascalCase(field?.name);
    let formattedType =
      field?.dataType === "Integer?" ? "Int?" : field?.dataType;
    newField.push(`${formatedField}: ${formattedType}`);
    allField.push(formatedField);
  });

  const hasId = allField.includes("id");

  let typedFields = newField
    .filter((field) => field !== "id: Int?")
    .concat(hasId ? "id: Int?" : "")
    .join(", ");

  let argField = allField
    .filter((field) => field !== "id")
    .concat(hasId ? "id" : "")
    .join(", ");

  result.typedFields = typedFields;
  result.argField = argField;

  return result;
};

export const buildDropDownImports = (fragment) => {
  if (findDropDownComponents(fragment).length == 0) return "";

  return `

import android.widget.ArrayAdapter
import android.widget.AdapterView
import androidx.navigation.fragment.navArgs
  `;
};

export const getDropDownFields = (fragment) => {
  if (findDropDownComponents(fragment).length == 0) return "";

  return `
  private lateinit var arrayAdapter: ArrayAdapter<String>
  private val idNameMap: HashMap<String, Int> = HashMap()
 
  `;
};

export const generateDropDownFragmentBinding = (fragment, configuration) => {
  // console.log("fragment:", fragment)
  if (findDropDownComponents(fragment).length == 0) return "";
  console.log("xx:", findDropDownComponent(fragment));
  let fields = findComponentsWithSourceProp(fragment);

  let action = findComponentsWithActionProp(fragment);

  if (fields?.length == 0 || action?.length == 0) {
    return `
    val arrayAdapter = ArrayAdapter<String>(requireContext(), R.layout.fragment_dropdown_item)
    arrayAdapter.add("Select Option")
    binding.${findDropDownComponent(
      fragment
    )}.setAdapter(arrayAdapter)
    `;
  }

  const { api } = configuration;

  const matchingApi = api.find((apiItem) => {
    return fields?.some((item) => item === apiItem.id);
  });

  let newField = [];

  matchingApi?.inputs?.forEach((field) => {
    let formattedType =
      field.name === "order"
        ? `"id,desc"`
        : field.name === "size"
        ? `"1,20"`
        : '""';

    newField.push(`${formattedType}`);
  });

  let fieldInput = newField.join(", ");

  const dropDown = findDropDownComponents(fragment);

  return `
  ${
    matchingApi !== undefined
      ? `arrayAdapter = ArrayAdapter(requireContext(), R.layout.fragment_dropdown_item)
        binding.autoCompleteTextView.setAdapter(arrayAdapter)
        ${dropDown
          .map(
            (element) =>
              `binding.autoCompleteTextView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
            val selectedItemName = arrayAdapter.getItem(position)
            ${element.props.name} = idNameMap[selectedItemName].toString()
        }`
          )
          .join("\n")}

        fetchDataFromSource(${fieldInput})
        `
      : `val languages = resources.getStringArray(R.array.programming_languages)
        val arrayAdapter = ArrayAdapter(requireContext(), R.layout.fragment_dropdown_item, languages)
        binding.autoCompleteTextView.setAdapter(arrayAdapter)`
  }
  `;
};

export const generateDropDownFunction = (fragment, configuration) => {
  if (findDropDownComponents(fragment).length == 0) return "";
  const { api } = configuration;
  let field = findComponentsWithSourceProp(fragment);

  let action = findComponentsWithActionProp(fragment);

  if (field?.length == 0) return "";
  if (action?.length == 0) return "";

  const matchingApi = api.find((apiItem) => {
    return field?.some((item) => item === apiItem.id);
  });

  const actionApi = api.find((apiItem) => {
    return action?.some((item) => item === apiItem.id);
  });

  const label = findDropDownComponents(fragment)[0].props.label.trim();
  const value = findDropDownComponents(fragment)[0].props.value.trim();

  const actionField = getFields(actionApi);
  const sourceField = getFields(matchingApi);

  if (matchingApi !== undefined) {
    return `
    private fun fetchDataFromSource(${sourceField.typedFields}) {
         requireActivity().hideSoftKeyboard()
        baasViewModel.${StringCaser(matchingApi.name, {
          casetype: "camelCase",
        })}(${sourceField.argField}).observe(viewLifecycleOwner) {
            when (it.status) {
                Status.ERROR -> snackBar(it.message ?: getString(R.string.something_went_wrong))
                Status.LOADING -> {
                    snackBar("Loading...")
                }

                Status.SUCCESS -> {
                    val data = it.data?.list
                    updateDropdown(data)
                }
            }
        }
       
    }

   
    
     private fun updateDropdown(data: ArrayList<Map<String, Any>>?) {
          val dataList = data?.map { map ->
            val id = map["${value}"].toString()
            val name = map["${label}"].toString()
            idNameMap[name] = id.substringBefore(".").toInt()
            name
         } ?: emptyList()

        arrayAdapter.clear()
        arrayAdapter.addAll(dataList)
        arrayAdapter.notifyDataSetChanged()
    }

    private fun handleSelected(${actionField.typedFields}) {
         requireActivity().hideSoftKeyboard()
        baasViewModel.${StringCaser(actionApi.name, {
          casetype: "camelCase",
        })}(${actionField.argField}).observe(viewLifecycleOwner) {
            when (it.status) {
                Status.ERROR -> snackBar(it.message ?: getString(R.string.something_went_wrong))
                Status.LOADING -> {
                    snackBar("Loading...")
                }
                Status.SUCCESS -> {
                   snackBar("success...")
                }
            }
        }
       
    }

    override fun onResume() {
        super.onResume()
        // Add any necessary code to handle onResume
    }

    override fun onDestroy() {
        super.onDestroy()
        // Add any necessary code to handle onDestroy
    }
  `;
  }
};
