export interface DynamicQueryStructure {
  select: string[] | "*";
  table: string;
  where?: Array<ConditionStructure>;
  join?: Array<DynamicQueryStructure & { foreignColumn: string }>;
  orderBy?: Array<OrderByStructure>;
}

export type ConditionStructure = (
  | {
      structureType: "condition";
      column: string;
      operation: WhereOperation;
      value: ConditionValue;
    }
  | {
      structureType: "nested";
      invert?: boolean;
      conditions: Array<ConditionStructure>;
    }
) & {
  concat: WhereType;
  structureType: "condition" | "nested";
};

export type ConditionValue = FieldType | Array<FieldType> | { start: FieldType; end: FieldType };
export type FieldType = number | string | Date | boolean;

export type WhereType = "OR" | "AND" | "_"; // _ represents initial where in (sub-)query

export type WhereOperation =
  | "eq" //	Equal
  | "neq" //	Not equal
  | "lt" //	Less than
  | "lte" //	Less than or equal to
  | "gt" //	Greater than
  | "gte" //	Greater than or equal to
  | "in" //	Included in an array
  | "notIn" //	Not included in an array
  | "contains" //	Contains
  | "notContains" //	Does not contain
  | "null" //	Is null
  | "notNull" //	Is not null
  | "between" //	Is between
  | "startsWith" //	Starts with
  | "endsWith" //	Ends with
  | "timespanEq"; // Date before x years (YYYY-01-01 <bis> YYYY-12-31)
// TODO: age between | age equals | age greater | age smaller

export type OrderByStructure = {
  column: string;
  order: OrderByType;
};

export type OrderByType = "ASC" | "DESC";

export type QueryResult = {
  [key: string]: FieldType | QueryResult | Array<QueryResult>;
};

export const exampleQuery: DynamicQueryStructure = {
  select: ["firstname", "lastname"],
  table: "member",
  where: [
    {
      structureType: "condition",
      concat: "_",
      column: "mail",
      operation: "endsWith",
      value: "@gmail.com",
    },
    {
      structureType: "nested",
      concat: "AND",
      conditions: [
        {
          structureType: "condition",
          concat: "_",
          column: "firstname",
          operation: "startsWith",
          value: "J",
        },
        {
          structureType: "condition",
          concat: "OR",
          column: "lastname",
          operation: "startsWith",
          value: "K",
        },
      ],
    },
  ],
  join: [
    {
      select: "*",
      table: "communication",
      foreignColumn: "sendNewsletter",
    },
    {
      select: "*",
      table: "membership",
      foreignColumn: "memberships",
      join: [
        {
          select: "*",
          table: "membership_status",
          foreignColumn: "status",
          where: [
            {
              structureType: "condition",
              concat: "_",
              column: "status",
              operation: "eq",
              value: "aktiv",
            },
          ],
        },
      ],
    },
  ],
  orderBy: [
    {
      column: "firstname",
      order: "ASC",
    },
    {
      column: "lastname",
      order: "ASC",
    },
  ],
};