
export interface SchemaOptions {
  label: string;
  value: string;
  valueType?: number;
  options?: SchemaOptions[];
}

export interface DataStructure {
  fieldId: string;
  type: "string" | "number" | "date" | "password" | "reference" | "multiReference" | "multiValue" | "file" | "datetime-local";
  displayName: string;
  hint?: string;
  required?: boolean;
  min?: number;
  max?: number;
  length?: number;
  hideFromCRUD?: boolean;
  hideFromList?: boolean;
  hideFromUser?: boolean;
  hideFromView?: boolean;
  isConfirmation?: boolean;
  confirmationField?: string;
  referenceId?: string;
  referenceStructure?: DataStructure[];
  referenceAlias?: string;
  referenceParentAlias?: string;
  referenceDisplay?: string;
  referenceDisplayIsTime?: boolean;
  referenceDisplayIsDate?: boolean;
  referenceValueTypeColumn?: string;
  multiReferenceEntryId?: string;
  multiReferenceEntryStructure?: DataStructure[];
  multiReferenceEntryAlias?: string;
  multiReferenceEntryDisplay?: string;
  multiReferenceEntryJoinId?: string;
  multiReferenceLocalForeignId?: string;
  options?: SchemaOptions[];
  unique?: boolean;
  defaultValue?: () => any;
}

export interface TableJoin{
  foreignTable: string,
  foreignAlias?: string,
  foreignTableId: string,
  foreignId: string,
  parentAlias?: string,
  type: "LEFT" | "RIGHT"
}

export interface OrderBy{
  column: string[],
  type: "ASC" | "DESC",
}

export interface TableConditions{
  queryColumn: string;
  value: string;
  operator: "=" | "!=" | ">" | ">=" | "<" | "<=" | "in" | "IS NULL" | "IS NOT NULL";
  logicalOperator?: "AND" | "OR"
}

export interface TableConditionGroups{
  condition: TableConditions[];
  logicalOperator?: "AND"[] | "OR"[];
}

export interface SelectRequestBody{
  table: string;
  columns?: string[];
  tableJoin?: TableJoin[];
  orderBy?: OrderBy;
  groupBy?: string[];
  where?: TableConditionGroups[];
  limit?: number;
  page?: number;
}

export interface InsertRequestBody{
  table: string;
  columns: string[];
  values: any[][];
}

export interface UpdateRequestBody{
  table: string;
  where?: TableConditionGroups[];
  columns: string[];
  values: string[];
}

export interface DeleteRequestBody{
  table: string;
  where?: TableConditionGroups[];
}

export const sanitizeString = (str: string) => {
  return String(str).replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, char => {
    switch (char) {
      case "\0":
        return "\\0";
      case "\x08":
        return "\\b";
      case "\x09":
        return "\\t";
      case "\x1a":
        return "\\z";
      case "\n":
        return "\\n";
      case "\r":
        return "\\r";
      case "\"":
      case "'":
      case "\\":
      case "%":
        return "\\" + char;
      default:
        return char;
    }
  });
}