import { StringCaser } from "@/utils/utils";

const blacklistedModels = ["stripe"];

export const buildTreeQLEndpoints = (schema, permissions) => {
  schema = schema?.filter((table) => {
    let isBlacklisted = blacklistedModels.findIndex(
      (pref) => table.model.indexOf(pref) != -1
    );
    if (isBlacklisted === -1) return true;

    return false;
  });

  const getEndpoints = buildGET(schema);
  const getListEndpoints = buildGETList(schema);
  const getPaginatedEndpoints = buildGETPaginated(schema);
  const getCreateEndpoints = buildCreate(schema);
  const getUpdateEndpoints = buildUpdate(schema);
  const getDeleteEndpoints = buildDelete(schema);

  return [
    ...getEndpoints,
    ...getListEndpoints,
    ...getPaginatedEndpoints,
    ...getCreateEndpoints,
    ...getUpdateEndpoints,
    ...getDeleteEndpoints,
  ];
};

const buildGET = (schema) => {
  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}OneTree`,
    name: `Get One ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })}`,
    method: "GET",
    description: "",
    route: `/v4/api/records/${table.model}/:id`,
    inputs: [
      { name: "id", type: "path", rules: "", dataType: "Integer?" },
      { name: "join", type: "query", rules: "", dataType: "String?" },
    ],
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "model", key: "model", value: "", valueType: "Object", parent: "" },
      {
        id: "mapping",
        key: "mapping",
        value: "",
        valueType: "Object",
        parent: "",
      },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};

const buildGETList = (schema) => {
  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}ListTree`,
    name: `Get ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })} List`,
    method: "GET",
    description: "",
    route: `/v4/api/records/${table.model}`,
    inputs: [
      { name: "order", type: "query", rules: "required", dataType: "String?" },
      { name: "size", type: "query", rules: "required", dataType: "String?" },
      { name: "filter", type: "query", rules: "", dataType: "String?" },
      { name: "join", type: "query", rules: "", dataType: "String?" },
    ],
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "list", key: "list", value: "", valueType: "Array", parent: "" },
      {
        id: "mapping",
        key: "mapping",
        value: "",
        valueType: "Object",
        parent: "",
      },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};

const buildGETPaginated = (schema) => {
  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}PaginatedTree`,
    name: `Get ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })} Paginated`,
    method: "GET",
    description: "",
    route: `/v4/api/records/${table.model}`,
    inputs: [
      { name: "order", type: "query", rules: "required", dataType: "String?" },
      { name: "page", type: "query", rules: "required", dataType: "String?" },
      { name: "filter", type: "query", rules: "", dataType: "String?" },
      { name: "join", type: "query", rules: "", dataType: "String?" },
    ],
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "list", key: "list", value: "", valueType: "Array", parent: "" },
      { id: "page", key: "page", value: "", valueType: "Number", parent: "" },
      { id: "limit", key: "limit", value: "", valueType: "Number", parent: "" },
      { id: "total", key: "total", value: "", valueType: "Number", parent: "" },
      {
        id: "mapping",
        key: "mapping",
        value: "",
        valueType: "Object",
        parent: "",
      },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};
const buildCreate = (schema) => {

  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}CreateTree`,
    name: `Create ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })}`,
    method: "POST",
    description: "",
    route: `/v4/api/records/${table.model}`,
    inputs: Object.keys(table.columns)
      .filter((c) => !["id", "create_at", "update_at"].includes(c))
      .map((col) => ({
        name: col,
        type: "body",
        rules: "",
        dataType: `${getType(table.columns[col])}?`,
      })),
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "data", key: "data", value: "", valueType: "Integer", parent: "" },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};
const buildUpdate = (schema) => {
  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}UpdateTree`,
    name: `Update ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })}`,
    method: "PUT",
    description: "",
    route: `/v4/api/records/${table.model}/:id`,
    inputs: Object.keys(table.columns)
      .filter((c) => !["create_at", "update_at"].includes(c))
      .map((col) => ({
        name: col,
        type: `${col === "id" ? "path" : "body"}`,
        rules: "",
        dataType: `${getType(table.columns[col])}?`,
      })),
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "data", key: "data", value: "", valueType: "Integer", parent: "" },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};

const buildDelete = (schema) => {
  return schema.map((table) => ({
    id: `_${StringCaser(table.model, { casetype: "camelCase" })}DeleteTree`,
    name: `Delete ${StringCaser(table.model, {
      casetype: "capitalize",
      separator: " ",
    })}`,
    method: "DELETE",
    description: "",
    route: `/v4/api/records/${table.model}/:id`,
    inputs: [{ name: "id", type: "path", rules: "", dataType: "Integer?" }],
    response: [
      {
        id: "error",
        key: "error",
        value: "",
        valueType: "Boolean",
        parent: "",
      },
      {
        id: "message",
        key: "message",
        value: "",
        valueType: "String",
        parent: "",
      },
      { id: "data", key: "data", value: "", valueType: "Integer", parent: "" },
    ],
    code: "",
    doc: "",
    unit: "",
    protected: true,
    authorizedRoles: [],
    imports: "",
    type: "default",
    group: "treeql",
    columns: table.columns,
  }));
};

export const getType = (type) => {
  switch (type) {
    case "varchar":
      return "String";
    case "text":
      return "String";
    case "mediumtext":
      return "String";
    case "longtext":
      return "String";
    case "tinyint":
      return "Integer";
    case "int":
      return "Integer";
    case "bigint":
      return "Integer";
    case "float":
      return "Number";
    case "double":
      return "Number";
    case "image":
      return "String";
    case "file":
      return "String";
    case "date":
      return "String";
    case "datetime":
      return "String";
    default:
      return type;
  }
};
