import { StringCaser } from "@/utils/utils";
import { getType } from "../utils/helpers";
import ChatRepositories from "../OtherUI/repositories/ChatRepositories";

export default (configuration) => {
  return `
package ${configuration.packageName}.repositories

import androidx.lifecycle.LiveData
import androidx.lifecycle.liveData
import ${configuration.packageName}.data.local.AppPreferences
import ${configuration.packageName}.model.remote.*
import ${configuration.packageName}.network.Resource
import ${configuration.packageName}.network.RemoteDataSource
import kotlinx.coroutines.Dispatchers
import okhttp3.MultipartBody

class APIRepository(
    private val remoteDataSource: RemoteDataSource,
    //private val preferences: AppPreferences
) {

    ${ChatRepositories(configuration)}
    ${buildRepositories(configuration.api)}
}
  `;
};

const buildRepositories = (apis) => {
  let endpoints = [];

  apis.map((api) => {
    endpoints.push(`
        fun ${StringCaser(api.name, {
          casetype: "camelCase",
        })}(${buildFunctionTypedArgs(
      api
    )}): LiveData<Resource<${getResponseName(api)}>> = 
          liveData(Dispatchers.IO) {
            emit(Resource.loading(null))
            val response = remoteDataSource.${StringCaser(api.name, {
              casetype: "camelCase",
            })}(${buildFunctionArgs(api)})
            emit(response)
          }
 
     `);
  });
  return endpoints.join("\n");
};

const getResponseName = (api) => {
  const modelName = StringCaser(api.name, { casetype: "PascalCase" });
  return `${modelName}Response`;
};

const getRequestName = (api) => {
  const modelName = StringCaser(api.name, { casetype: "PascalCase" });
  return `${modelName}Request`;
};

const buildFunctionTypedArgs = (api) => {
  const body = buildBody(
    api.inputs.filter((input) => input.type == "body"),
    api
  );
  const paths = buildTypedPaths(
    api.inputs.filter((input) => input.type == "path"),
    api
  );
  const query = buildTypedQueries(
    api.inputs.filter((input) => input.type == "query"),
    api
  );
  const multipart = buildTypedMultipart(
    api.inputs.filter((input) => input.type == "multipart"),
    api
  );
  return `${body} ${paths} ${query} ${multipart}`;
};

const buildFunctionArgs = (api) => {
  const body =
    api.inputs.filter((input) => input.type == "body").length > 0
      ? "request,"
      : "";
  const paths = buildPaths(
    api.inputs.filter((input) => input.type == "path"),
    api
  );
  const query = buildQueries(
    api.inputs.filter((input) => input.type == "query"),
    api
  );
  const multipart = buildMultipart(
    api.inputs.filter((input) => input.type == "multipart"),
    api
  );
  return `${body} ${paths} ${query} ${multipart}`;
};

const buildMultipart = (inputs, api) => {
  if (inputs.length == 0) return "";
  // file: MultipartBody.Part
  return ` ${inputs.map((input) => `${input.name}`).join(", \n")}`;
};

const buildTypedMultipart = (inputs, api) => {
  if (inputs.length == 0) return "";
  //file: MultipartBody.Part
  return ` ${inputs
    .map((input) => ` ${input.name}: MultipartBody.Part`)
    .join(", \n")}`;
};

const buildPaths = (inputs, api) => {
  if (inputs.length == 0) return "";
  // id: Int
  return ` ${inputs
    .map(
      (input, index) => ` ${StringCaser(input.name, { casetype: "camelCase" })}`
    )
    .map(
      (query, index, array) =>
        ` ${query}${index === array.length - 1 ? "," : ""}`
    )
    .join(", \n")}`;
};

const buildTypedPaths = (inputs, api) => {
  if (inputs.length == 0) return "";
  //@Path("id") id: Int
  return ` ${inputs
    .map(
      (input) =>
        ` ${StringCaser(input.name, { casetype: "camelCase" })}: ${getType(
          input.dataType
        )}`
    )
    .map(
      (query, index, array) =>
        ` ${query}${index === array.length - 1 ? "," : ""}`
    )
    .join(", \n")}`;
};

const buildTypedQueries = (inputs, api) => {
  if (inputs.length == 0) return "";
  //chatId: Int

  return ` ${inputs
    .map(
      (input) =>
        ` ${StringCaser(input.name, { casetype: "camelCase" })}: ${getType(
          input.dataType
        )}`
    )
    .map(
      (query, index, array) =>
        ` ${query}${index === array.length - 1 ? "," : ""}`
    )
    .join(", \n")} `;
};

const buildQueries = (inputs, api) => {
  if (inputs.length == 0) return "";
  //chatId

  return ` ${inputs
    .map(
      (input, index) => ` ${StringCaser(input.name, { casetype: "camelCase" })}`
    )
    .map(
      (query, index, array) =>
        ` ${query}${index === array.length - 1 ? "," : ""}`
    )
    .join(", \n")} `;
};

const buildBody = (inputs, api) => {
  if (inputs.length == 0) return "";
  //request: TranslateRequest
  const requestName = StringCaser(api.name, { casetype: "PascalCase" });
  return ` request: ${requestName}Request, `;
};
