import { StringCaser } from "@/components/WebExportReact/src/utils/helpers";
import { getComponentViewBindingId } from "./helpers";
export const underscoreToPascalCase = (input) => {
  return input.replace(/_([a-z])/g, (_, group1) => group1.toUpperCase());
};

export function findComponentsWithSubmitAction(data, result = []) {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if ("components" in item) {
      findComponentsWithSubmitAction(item.components, result);
    }
    if ("children" in item) {
      findComponentsWithSubmitAction(item.children, result);
    }
    if (
      "props" in item &&
      item.props.onclick === "submit" &&
      item.props.to !== ""
    ) {
      result.push(item);
    }
  }
  return result;
}

export function findFormType(data, result = []) {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if ("components" in item) {
      findFormType(item.components, result);
    }
    if (item.name === "EditFormLayout" && item.props.source.length > 0) {
      result.push(item);
    }
  }
  return result;
}

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

  for (const item of data) {
    if ("components" in item) {
      findComponentsWithNameFields(item.components, result);
    }
    if ("children" in item) {
      findComponentsWithNameFields(item.children, result);
    }
    if ("props" in item && item.props?.name?.length > 0) {
      result.push(item);
    }
  }
  return result;
}

const getTextFields = (data, result = []) => {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if ("components" in item) {
      getTextFields(item.components, result);
    }
    if ("children" in item) {
      getTextFields(item.children, result);
    }

    if (item.type === "element" && "props" in item && item.props.name) {
      result.push(item.props.name);
    }
  }
  return result;
};

export const buildFormApiArgs = (api = "") => {
  let input = api?.inputs
    ?.map((input) => `${StringCaser(input.name, { casetype: "camelCase" })}`)
    .join(",");

  return input;
};

export const filterApiById = (fragment, configuration, type) => {
  const { api } = configuration;
  const comp = findComponentsWithSubmitAction(fragment);
  let matchingApi = null;

  api.find((apiItem) => {
    comp.forEach((component) => {
      const propValue = component.props?.[type];

      if (apiItem.id === propValue) {
        matchingApi = apiItem;
        return true;
      }
    });

    return matchingApi !== null;
  });
  return matchingApi;
};

export function convertToFunctionName(inputString) {
  const withoutEdit = inputString.replace("Edit", "");
  const withoutSpaces = withoutEdit.replace(/\s+/g, "");

  const camelCaseString = withoutSpaces.charAt(0) + withoutSpaces.slice(1);

  const resultString = `get${camelCaseString}`;

  return resultString;
}

export const generateSubmitImports = (fragment) => {
  if (findComponentsWithSubmitAction(fragment).length == 0) return "";
  return `
import androidx.core.widget.doAfterTextChanged
// import android.util.Log
    `;
};

export const getFormFragmentFields = (fragment) => {
  if (findComponentsWithSubmitAction(fragment).length == 0) return "";
  let fields = getTextFields(fragment);

  return fields
    .map((field) => {
      return `
    private var ${underscoreToPascalCase(field)} = ""
    `;
    })
    .join("");
};

export const generateSubmitActionListeners = (fragment, configuration) => {
  if (findComponentsWithSubmitAction(fragment).length == 0) return "";
  const api = filterApiById(fragment, configuration, "to");


  let fields = api?.inputs;

  let newField = [];
  let allNewField = [];
  fields?.map((field) => {
    let formatedField = underscoreToPascalCase(field.name);

    let formattedType =
      field.dataType === "Integer?" && field.name !== "user_id"
        ? `${formatedField}.toInt()`
        : formatedField;

    allNewField.push(formattedType);
    newField.push(formatedField);
  });

  let nonEmptyFieldsCheck =
    newField
      .filter((field) => field !== "id" && field !== "userId")
      .join(".isNotEmpty() && ") + ".isNotEmpty()";

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

  let allFields = allNewField
    .filter((field) => field !== "id.toInt()")
    .concat(hasId ? "id.toInt()" : "")
    .join(", ");

  let button = findComponentsWithSubmitAction(fragment);
  let textField = findComponentsWithNameFields(fragment);

  let content = [];
  for (const element of button) {
    content.push(`
          binding.${getComponentViewBindingId(element)}.setOnClickWithDebounce {
                if (${nonEmptyFieldsCheck}) ${StringCaser(fragment.name, {
      separator: "",
      casetype: "camelCase",
    })}(${allFields})
            else snackBar(getString(R.string.empty_location))
            }
           ${textField
             .map((text) => {
               `binding.${getComponentViewBindingId(
                 text
               )}.doAfterTextChanged {${StringCaser(text.props.name, {
                 separator: "",
                 casetype: "camelCase",
               })} = it.toString() }`;
             })
             .join("\n")}
      `);
  }
  return content.join("\n");
};

export const generateSubmitFunction = (fragment, configuration) => {
  if (findComponentsWithSubmitAction(fragment).length == 0) return "";
  const api = filterApiById(fragment, configuration, "to");

  let fields = api?.inputs;
  // let newField = [];
  // fields.map((field) => {
  //   let formatedField = underscoreToPascalCase(field);
  //   newField.push(formatedField);
  // });
  let newField = [];
  let allField = [];
  fields?.forEach((field) => {
    let formatedField = underscoreToPascalCase(field.name);

    let formattedType = field.dataType === "Integer?" ? "Int?" : "String?";

    allField.push(formatedField);
    newField.push(`${formatedField}: ${formattedType}`);
  });

  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(", ");

  return `
    private fun ${StringCaser(fragment.name, {
      separator: "",
      casetype: "camelCase",
    })}(${typedFields}) {
        requireActivity().hideSoftKeyboard()
        baasViewModel.${StringCaser(api?.name, {
          casetype: "camelCase",
        })}(${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...")

                    val data = it.data
                    data?.let { it1 -> it1.message?.let { it2 -> Log.d("", it2) } }
                    
                }
            }
        }
    }   
`;
};

export const generateFormDetails = (fragment, configuration) => {
  if (findFormType(fragment).length === 0) return "";
  const field = findFormType(fragment);
  console.log(field);

  const { api } = configuration;

  const matchingApi = api.find((apiItem) => {
    for (const component of fragment.components) {
      const propValue = component.props?.source;
      if (apiItem.id === propValue) {
        return true;
      }
    }
  });

  let newField = [];
  matchingApi?.inputs?.forEach((field) => {
    let formatedField = underscoreToPascalCase(field.name);

    let formattedType = field.dataType === "Integer?" ? "Int?" : field.dataType;

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

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

  let textField = findComponentsWithNameFields(fragment);

  const setTextFieldsCode = textField
    .map(
      (text) =>
        `binding.${getComponentViewBindingId(text)}.setText(data?.${
          text.props.name
        })`
    )
    .join("\n");

  return `
   private fun ${convertToFunctionName(fragment.name)}(${typedFields}) {
        requireActivity().hideSoftKeyboard()

        baasViewModel.${StringCaser(matchingApi?.name, {
          casetype: "camelCase",
        })}(${buildFormApiArgs(matchingApi)}).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
                    ${setTextFieldsCode}
                }
            }
        }
    }
    
  `;
};

export const callGetFunction = (fragment, configuration) => {
  // if (findFormType(fragment)[0]?.name !== "EditFormLayout") return "";
  const field = findFormType(fragment);

  const { api } = configuration;

  const matchingApi = api.find((apiItem) => {
    const propValue = field[0]?.props?.source;
    return apiItem.id === propValue;
  });

  let newField = [];
  matchingApi?.inputs?.forEach((field) => {
    let formattedType = field.dataType === "Integer?" ? 1 : '""';

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

  let fieldInput = newField.join(", ");
  return `${convertToFunctionName(fragment.name)}(${fieldInput})`;
};
