package pgm

import (
	"context"

	"github.com/jackc/pgx/v5"
)

type (
	DeleteCluase interface {
		WhereOrExec
	}

	deleteQry struct {
		table     string
		condition []Conditioner
		args      []any
		debug     bool
	}
)

// WARNING: DELETE without WHERE clause will delete ALL rows in the table.
// Always use Where() to specify conditions unless you intentionally want to delete all rows.
// Example:
//   table.Delete().Where(field.Eq(value)).Exec(ctx)  // Safe
//   table.Delete().Exec(ctx)                          // Deletes ALL rows!

func (q *deleteQry) Where(cond ...Conditioner) WhereOrExec {
	q.condition = append(q.condition, cond...)
	return q
}

func (q *deleteQry) Exec(ctx context.Context) error {
	_, err := poolPGX.Load().Exec(ctx, q.String(), q.args...)
	if err != nil {
		return err
	}
	return nil
}

func (q *deleteQry) ExecTx(ctx context.Context, tx pgx.Tx) error {
	_, err := tx.Exec(ctx, q.String(), q.args...)
	if err != nil {
		return err
	}

	return nil
}

func (q *deleteQry) String() string {
	sb := getSB()
	defer putSB(sb)

	n := len("DELETE FROM ") + len(q.table) + 20
	sb.Grow(n)

	// DELETE
	sb.WriteString("DELETE FROM ")
	sb.WriteString(q.table)

	// WHERE
	if len(q.condition) > 0 {
		sb.WriteString(" WHERE ")
		var argIdx int
		for i, c := range q.condition {
			argIdx = len(q.args)
			if i > 0 {
				sb.WriteString(" AND ")
			}
			sb.WriteString(c.Condition(&q.args, argIdx))
		}
	}

	return sb.String()
}
