package main

import (
    "context"
    "database/sql"
    "fmt"
    "log"
    "time"
    
    "github.com/jmoiron/sqlx"
    _ "github.com/lib/pq" // PostgreSQL driver
    "yourpackage/utils"
)

func main() {
    // Inisialisasi koneksi database
    db, err := sqlx.Connect("postgres", "user=postgres dbname=testdb sslmode=disable")
    if err != nil {
        log.Fatalf("Failed to connect to database: %v", err)
    }
    defer db.Close()
    
    // Inisialisasi QueryBuilder
    qb := utils.NewQueryBuilder(utils.DBTypePostgreSQL)
    
    // Contoh penggunaan
    simpleQueryExample(db, qb)
    complexQueryExample(db, qb)
    nestedJoinExample(db, qb)
    multiJoinExample(db, qb)
    commonQueriesExample(db, qb)
    jsonQueryExample(db, qb)
    windowFunctionExample(db, qb)
    cteExample(db, qb)
    unionExample(db, qb)
    aggregateExample(db, qb)
}

func simpleQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Simple Query Example ===")
    
    // Query sederhana dengan filter
    query := utils.DynamicQuery{
        From: "users",
        Fields: []utils.SelectField{
            {Expression: "id", Alias: "user_id"},
            {Expression: "name", Alias: "user_name"},
            {Expression: "email"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "active"},
                    {Column: "created_at", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(0, -1, 0)},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "name", Order: "ASC"},
        },
        Limit: 10,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing simple query: %v", err)
        return
    }
    
    fmt.Printf("Found %d users\n", len(results))
    for _, user := range results {
        fmt.Printf("User: %+v\n", user)
    }
}

func complexQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Complex Query Example ===")
    
    // Query dengan nested filter dan berbagai operator
    query := utils.DynamicQuery{
        From: "orders",
        Fields: []utils.SelectField{
            {Expression: "id", Alias: "order_id"},
            {Expression: "customer_id"},
            {Expression: "total_amount"},
            {Expression: "order_date"},
            {Expression: "status"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpIn, Value: []string{"completed", "processing"}},
                    {Column: "total_amount", Operator: utils.OpGreaterThan, Value: 1000},
                },
                LogicOp: "AND",
            },
            {
                Filters: []utils.DynamicFilter{
                    {Column: "order_date", Operator: utils.OpBetween, Value: []interface{}{time.Now().AddDate(0, -3, 0), time.Now()}},
                    {Column: "customer_id", Operator: utils.OpNotIn, Value: []int{1, 2, 3}},
                },
                LogicOp: "OR",
            },
        },
        Sort: []utils.SortField{
            {Column: "order_date", Order: "DESC"},
            {Column: "total_amount", Order: "DESC"},
        },
        Limit: 20,
        Offset: 10,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing complex query: %v", err)
        return
    }
    
    fmt.Printf("Found %d orders\n", len(results))
    for _, order := range results {
        fmt.Printf("Order: %+v\n", order)
    }
}

func nestedJoinExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Nested Join Example ===")
    
    // Query dengan nested join
    query := utils.DynamicQuery{
        From: "customers",
        Fields: []utils.SelectField{
            {Expression: "customers.id", Alias: "customer_id"},
            {Expression: "customers.name", Alias: "customer_name"},
            {Expression: "orders.id", Alias: "order_id"},
            {Expression: "orders.total_amount"},
            {Expression: "order_items.product_id"},
            {Expression: "order_items.quantity"},
            {Expression: "products.name", Alias: "product_name"},
        },
        Joins: []utils.Join{
            {
                Type: "LEFT",
                Table: "orders",
                Alias: "orders",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "customers.id", Operator: utils.OpEqual, Value: "orders.customer_id"},
                    },
                },
            },
            {
                Type: "LEFT",
                Table: "order_items",
                Alias: "order_items",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "orders.id", Operator: utils.OpEqual, Value: "order_items.order_id"},
                    },
                },
            },
            {
                Type: "LEFT",
                Table: "products",
                Alias: "products",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "order_items.product_id", Operator: utils.OpEqual, Value: "products.id"},
                    },
                },
            },
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "customers.status", Operator: utils.OpEqual, Value: "active"},
                    {Column: "orders.status", Operator: utils.OpEqual, Value: "completed"},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "customers.name", Order: "ASC"},
            {Column: "orders.id", Order: "DESC"},
        },
        Limit: 50,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing nested join query: %v", err)
        return
    }
    
    fmt.Printf("Found %d customer-order-product records\n", len(results))
    for _, record := range results {
        fmt.Printf("Record: %+v\n", record)
    }
}

func multiJoinExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Multi Join Example ===")
    
    // Query dengan multiple join types
    query := utils.DynamicQuery{
        From: "employees",
        Fields: []utils.SelectField{
            {Expression: "employees.id", Alias: "employee_id"},
            {Expression: "employees.name", Alias: "employee_name"},
            {Expression: "departments.name", Alias: "department_name"},
            {Expression: "projects.name", Alias: "project_name"},
            {Expression: "tasks.title", Alias: "task_title"},
            {Expression: "task_assignments.assigned_date"},
        },
        Joins: []utils.Join{
            {
                Type: "INNER",
                Table: "departments",
                Alias: "departments",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "employees.department_id", Operator: utils.OpEqual, Value: "departments.id"},
                    },
                },
            },
            {
                Type: "LEFT",
                Table: "task_assignments",
                Alias: "task_assignments",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "employees.id", Operator: utils.OpEqual, Value: "task_assignments.employee_id"},
                    },
                },
            },
            {
                Type: "LEFT",
                Table: "tasks",
                Alias: "tasks",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "task_assignments.task_id", Operator: utils.OpEqual, Value: "tasks.id"},
                    },
                },
            },
            {
                Type: "LEFT",
                Table: "projects",
                Alias: "projects",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "tasks.project_id", Operator: utils.OpEqual, Value: "projects.id"},
                    },
                },
            },
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "employees.status", Operator: utils.OpEqual, Value: "active"},
                    {Column: "departments.status", Operator: utils.OpEqual, Value: "active"},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "departments.name", Order: "ASC"},
            {Column: "employees.name", Order: "ASC"},
            {Column: "task_assignments.assigned_date", Order: "DESC"},
        },
        Limit: 100,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing multi join query: %v", err)
        return
    }
    
    fmt.Printf("Found %d employee-task-project records\n", len(results))
    for _, record := range results {
        fmt.Printf("Record: %+v\n", record)
    }
}

func commonQueriesExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Common Queries Example ===")
    
    // 1. Query dengan LIKE/ILIKE
    likeQuery := utils.DynamicQuery{
        From: "products",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "name"},
            {Expression: "price"},
            {Expression: "category"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "name", Operator: utils.OpILike, Value: "%laptop%"},
                    {Column: "category", Operator: utils.OpEqual, Value: "electronics"},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "price", Order: "ASC"},
        },
        Limit: 10,
    }
    
    var products []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, likeQuery, &products)
    if err != nil {
        log.Printf("Error executing LIKE query: %v", err)
    } else {
        fmt.Printf("Found %d products matching 'laptop'\n", len(products))
    }
    
    // 2. Query dengan pagination
    page := 2
    pageSize := 20
    paginationQuery := utils.DynamicQuery{
        From: "orders",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "customer_id"},
            {Expression: "total_amount"},
            {Expression: "order_date"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "completed"},
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "order_date", Order: "DESC"},
        },
        Limit:  pageSize,
        Offset: (page - 1) * pageSize,
    }
    
    var orders []map[string]interface{}
    err = qb.ExecuteQuery(context.Background(), db, paginationQuery, &orders)
    if err != nil {
        log.Printf("Error executing pagination query: %v", err)
    } else {
        fmt.Printf("Found %d orders on page %d\n", len(orders), page)
    }
    
    // 3. Query dengan NULL/NOT NULL
    nullQuery := utils.DynamicQuery{
        From: "customers",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "name"},
            {Expression: "email"},
            {Expression: "phone"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "email", Operator: utils.OpNotNull},
                    {Column: "phone", Operator: utils.OpNull},
                },
                LogicOp: "AND",
            },
        },
        Limit: 10,
    }
    
    var customers []map[string]interface{}
    err = qb.ExecuteQuery(context.Background(), db, nullQuery, &customers)
    if err != nil {
        log.Printf("Error executing NULL query: %v", err)
    } else {
        fmt.Printf("Found %d customers with email but no phone\n", len(customers))
    }
    
    // 4. Query dengan BETWEEN
    betweenQuery := utils.DynamicQuery{
        From: "transactions",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "account_id"},
            {Expression: "amount"},
            {Expression: "transaction_date"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "amount", Operator: utils.OpBetween, Value: []interface{}{100, 1000}},
                    {Column: "transaction_date", Operator: utils.OpBetween, Value: []interface{}{time.Now().AddDate(0, -1, 0), time.Now()}},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "transaction_date", Order: "DESC"},
        },
        Limit: 20,
    }
    
    var transactions []map[string]interface{}
    err = qb.ExecuteQuery(context.Background(), db, betweenQuery, &transactions)
    if err != nil {
        log.Printf("Error executing BETWEEN query: %v", err)
    } else {
        fmt.Printf("Found %d transactions between $100 and $1000 in the last month\n", len(transactions))
    }
}

func jsonQueryExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== JSON Query Example ===")
    
    // Query dengan operasi JSON
    query := utils.DynamicQuery{
        From: "products",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "name"},
            {Expression: "price"},
            {Expression: "attributes"},
        },
        JsonOperations: []utils.JsonOperation{
            {
                Type:   "extract",
                Column: "attributes",
                Path:   "$.color",
                Alias:  "color",
            },
            {
                Type:   "extract",
                Column: "attributes",
                Path:   "$.size",
                Alias:  "size",
            },
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {
                        Column:   "attributes",
                        Operator: utils.OpJsonContains,
                        Value:    map[string]interface{}{"category": "electronics"},
                        Options:  map[string]interface{}{"path": "$"},
                    },
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "name", Order: "ASC"},
        },
        Limit: 10,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing JSON query: %v", err)
        return
    }
    
    fmt.Printf("Found %d products with JSON attributes\n", len(results))
    for _, product := range results {
        fmt.Printf("Product: %+v\n", product)
    }
}

func windowFunctionExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Window Function Example ===")
    
    // Query dengan window functions
    query := utils.DynamicQuery{
        From: "sales",
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "salesperson_id"},
            {Expression: "amount"},
            {Expression: "sale_date"},
        },
        WindowFunctions: []utils.WindowFunction{
            {
                Function: "ROW_NUMBER",
                Over:     "salesperson_id",
                OrderBy:  "amount DESC",
                Alias:    "sales_rank",
            },
            {
                Function: "SUM",
                Over:     "salesperson_id",
                OrderBy:  "sale_date",
                Frame:    "ROWS UNBOUNDED PRECEDING",
                Alias:    "running_total",
            },
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "sale_date", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(0, -6, 0)},
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "salesperson_id", Order: "ASC"},
            {Column: "amount", Order: "DESC"},
        },
        Limit: 50,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing window function query: %v", err)
        return
    }
    
    fmt.Printf("Found %d sales records with window functions\n", len(results))
    for _, sale := range results {
        fmt.Printf("Sale: %+v\n", sale)
    }
}

func cteExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== CTE Example ===")
    
    // Query dengan CTE
    query := utils.DynamicQuery{
        CTEs: []utils.CTE{
            {
                Name: "monthly_sales",
                Query: utils.DynamicQuery{
                    Fields: []utils.SelectField{
                        {Expression: "salesperson_id"},
                        {Expression: "EXTRACT(MONTH FROM sale_date) AS month"},
                        {Expression: "SUM(amount) AS total"},
                    },
                    From: "sales",
                    Filters: []utils.FilterGroup{
                        {
                            Filters: []utils.DynamicFilter{
                                {Column: "sale_date", Operator: utils.OpGreaterThanEqual, Value: time.Now().AddDate(-1, 0, 0)},
                            },
                        },
                    },
                    GroupBy: []string{"salesperson_id", "EXTRACT(MONTH FROM sale_date)"},
                },
            },
            {
                Name: "top_salespeople",
                Query: utils.DynamicQuery{
                    Fields: []utils.SelectField{
                        {Expression: "salesperson_id"},
                        {Expression: "SUM(total) AS yearly_total"},
                    },
                    From: "monthly_sales",
                    GroupBy: []string{"salesperson_id"},
                    Having: []utils.FilterGroup{
                        {
                            Filters: []utils.DynamicFilter{
                                {Column: "SUM(total)", Operator: utils.OpGreaterThan, Value: 10000},
                            },
                        },
                    },
                },
            },
        },
        Fields: []utils.SelectField{
            {Expression: "salespeople.id"},
            {Expression: "salespeople.name"},
            {Expression: "top_salespeople.yearly_total"},
        },
        From: "salespeople",
        Joins: []utils.Join{
            {
                Type: "INNER",
                Table: "top_salespeople",
                Alias: "top_salespeople",
                OnConditions: utils.FilterGroup{
                    Filters: []utils.DynamicFilter{
                        {Column: "salespeople.id", Operator: utils.OpEqual, Value: "top_salespeople.salesperson_id"},
                    },
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "top_salespeople.yearly_total", Order: "DESC"},
        },
        Limit: 10,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing CTE query: %v", err)
        return
    }
    
    fmt.Printf("Found %d top salespeople\n", len(results))
    for _, salesperson := range results {
        fmt.Printf("Salesperson: %+v\n", salesperson)
    }
}

func unionExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== UNION Example ===")
    
    // Query dengan UNION
    query := utils.DynamicQuery{
        Fields: []utils.SelectField{
            {Expression: "id"},
            {Expression: "name"},
            {Expression: "email"},
            {Expression: "'customer' AS user_type"},
        },
        From: "customers",
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "active"},
                },
            },
        },
        Unions: []utils.Union{
            {
                Type: "UNION ALL",
                Query: utils.DynamicQuery{
                    Fields: []utils.SelectField{
                        {Expression: "id"},
                        {Expression: "name"},
                        {Expression: "email"},
                        {Expression: "'employee' AS user_type"},
                    },
                    From: "employees",
                    Filters: []utils.FilterGroup{
                        {
                            Filters: []utils.DynamicFilter{
                                {Column: "status", Operator: utils.OpEqual, Value: "active"},
                            },
                        },
                    },
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "name", Order: "ASC"},
        },
        Limit: 20,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing UNION query: %v", err)
        return
    }
    
    fmt.Printf("Found %d users (customers + employees)\n", len(results))
    for _, user := range results {
        fmt.Printf("User: %+v\n", user)
    }
}

func aggregateExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Aggregate Example ===")
    
    // Query dengan fungsi agregasi
    query := utils.DynamicQuery{
        Fields: []utils.SelectField{
            {Expression: "category"},
            {Expression: "COUNT(*) AS product_count"},
            {Expression: "AVG(price) AS avg_price"},
            {Expression: "MIN(price) AS min_price"},
            {Expression: "MAX(price) AS max_price"},
            {Expression: "SUM(stock_quantity) AS total_stock"},
        },
        From: "products",
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "active"},
                },
            },
        },
        GroupBy: []string{"category"},
        Having: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "COUNT(*)", Operator: utils.OpGreaterThan, Value: 5},
                },
            },
        },
        Sort: []utils.SortField{
            {Column: "product_count", Order: "DESC"},
        },
        Limit: 10,
    }
    
    var results []map[string]interface{}
    err := qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing aggregate query: %v", err)
        return
    }
    
    fmt.Printf("Found %d product categories\n", len(results))
    for _, category := range results {
        fmt.Printf("Category: %+v\n", category)
    }
}

func crudOperationsExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== CRUD Operations Example ===")
    
    // INSERT
    insertData := utils.InsertData{
        Columns: []string{"name", "email", "status", "created_at"},
        Values:  []interface{}{"John Doe", "john@example.com", "active", time.Now()},
        JsonValues: map[string]interface{}{
            "preferences": map[string]interface{}{
                "theme":    "dark",
                "language": "en",
            },
        },
    }
    
    result, err := qb.ExecuteInsert(context.Background(), db, "customers", insertData, "id")
    if err != nil {
        log.Printf("Error executing INSERT: %v", err)
        return
    }
    
    id, err := result.LastInsertId()
    if err != nil {
        log.Printf("Error getting inserted ID: %v", err)
        return
    }
    
    fmt.Printf("Inserted customer with ID: %d\n", id)
    
    // UPDATE
    updateData := utils.UpdateData{
        Columns: []string{"name", "status"},
        Values:  []interface{}{"John Smith", "inactive"},
        JsonUpdates: map[string]utils.JsonUpdate{
            "preferences": {
                Path:  "$.theme",
                Value: "light",
            },
        },
    }
    
    filters := []utils.FilterGroup{
        {
            Filters: []utils.DynamicFilter{
                {Column: "id", Operator: utils.OpEqual, Value: id},
            },
        },
    }
    
    result, err = qb.ExecuteUpdate(context.Background(), db, "customers", updateData, filters, "updated_at")
    if err != nil {
        log.Printf("Error executing UPDATE: %v", err)
        return
    }
    
    rowsAffected, err := result.RowsAffected()
    if err != nil {
        log.Printf("Error getting rows affected: %v", err)
        return
    }
    
    fmt.Printf("Updated %d customer(s)\n", rowsAffected)
    
    // DELETE
    result, err = qb.ExecuteDelete(context.Background(), db, "customers", filters)
    if err != nil {
        log.Printf("Error executing DELETE: %v", err)
        return
    }
    
    rowsAffected, err = result.RowsAffected()
    if err != nil {
        log.Printf("Error getting rows affected: %v", err)
        return
    }
    
    fmt.Printf("Deleted %d customer(s)\n", rowsAffected)
}


func mongoExample() {
    fmt.Println("\n=== MongoDB Example ===")
    
    // Inisialisasi koneksi MongoDB
    client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        log.Fatalf("Failed to connect to MongoDB: %v", err)
    }
    defer client.Disconnect(context.Background())
    
    db := client.Database("testdb")
    collection := db.Collection("users")
    
    // Inisialisasi MongoQueryBuilder
    mqb := utils.NewMongoQueryBuilder()
    
    // Query sederhana
    query := utils.DynamicQuery{
        Fields: []utils.SelectField{
            {Expression: "name"},
            {Expression: "email"},
            {Expression: "status"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "active"},
                    {Column: "age", Operator: utils.OpGreaterThan, Value: 18},
                },
                LogicOp: "AND",
            },
        },
        Sort: []utils.SortField{
            {Column: "name", Order: "ASC"},
        },
        Limit: 10,
    }
    
    var results []map[string]interface{}
    err = mqb.ExecuteFind(context.Background(), collection, query, &results)
    if err != nil {
        log.Printf("Error executing MongoDB query: %v", err)
        return
    }
    
    fmt.Printf("Found %d users\n", len(results))
    for _, user := range results {
        fmt.Printf("User: %+v\n", user)
    }
    
    // Aggregation pipeline
    aggQuery := utils.DynamicQuery{
        Fields: []utils.SelectField{
            {Expression: "department", Alias: "_id"},
            {Expression: "COUNT(*)", Alias: "employee_count"},
            {Expression: "AVG(salary)", Alias: "avg_salary"},
        },
        Filters: []utils.FilterGroup{
            {
                Filters: []utils.DynamicFilter{
                    {Column: "status", Operator: utils.OpEqual, Value: "active"},
                },
            },
        },
        GroupBy: []string{"department"},
        Sort: []utils.SortField{
            {Column: "employee_count", Order: "DESC"},
        },
        Limit: 10,
    }
    
    var aggResults []map[string]interface{}
    err = mqb.ExecuteAggregate(context.Background(), collection, aggQuery, &aggResults)
    if err != nil {
        log.Printf("Error executing MongoDB aggregation: %v", err)
        return
    }
    
    fmt.Printf("Found %d departments\n", len(aggResults))
    for _, dept := range aggResults {
        fmt.Printf("Department: %+v\n", dept)
    }
}

func queryParserExample(db *sqlx.DB, qb *utils.QueryBuilder) {
    fmt.Println("\n=== Query Parser Example ===")
    
    // Inisialisasi QueryParser
    qp := utils.NewQueryParser()
    
    // Parse URL query parameters
    values := url.Values{}
    values.Add("fields", "id,name,email,status")
    values.Add("filter[status][_eq]", "active")
    values.Add("filter[created_at][_gte]", "2023-01-01")
    values.Add("filter[age][_between]", "18,65")
    values.Add("sort", "+name,-created_at")
    values.Add("limit", "20")
    values.Add("offset", "10")
    
    // Parse query parameters into DynamicQuery
    query, err := qp.ParseQuery(values, "users")
    if err != nil {
        log.Printf("Error parsing query: %v", err)
        return
    }
    
    // Execute the parsed query
    var results []map[string]interface{}
    err = qb.ExecuteQuery(context.Background(), db, query, &results)
    if err != nil {
        log.Printf("Error executing parsed query: %v", err)
        return
    }
    
    fmt.Printf("Found %d users using parsed query\n", len(results))
    for _, user := range results {
        fmt.Printf("User: %+v\n", user)
    }
}
