package crud

import (
	"context"
	"fmt"
	"strings"
)

type scopeKey struct{}

// RowScope 行级组织范围：OrgUnitIDs 非空时限制可读范围；WriteOrgUnit 写入新建行。
type RowScope struct {
	OrgUnitIDs   []int64
	WriteOrgUnit int64
}

func WithRowScope(ctx context.Context, s RowScope) context.Context {
	return context.WithValue(ctx, scopeKey{}, s)
}

func RowScopeFrom(ctx context.Context) RowScope {
	v, _ := ctx.Value(scopeKey{}).(RowScope)
	return v
}

func appendOrgFilter(where []string, args []any, argN int, orgIDs []int64) ([]string, []any, int) {
	if len(orgIDs) == 0 {
		return where, args, argN
	}
	ph := make([]string, 0, len(orgIDs))
	for _, id := range orgIDs {
		ph = append(ph, fmt.Sprintf("$%d", argN))
		args = append(args, id)
		argN++
	}
	where = append(where, fmt.Sprintf("(org_unit_id IS NULL OR org_unit_id IN (%s))", strings.Join(ph, ",")))
	return where, args, argN
}

func matchOrgScope(row map[string]any, orgIDs []int64) bool {
	if len(orgIDs) == 0 {
		return true
	}
	v, ok := row["org_unit_id"]
	if !ok || v == nil {
		return true
	}
	oid := toInt64(v)
	if oid == 0 {
		return true
	}
	for _, id := range orgIDs {
		if id == oid {
			return true
		}
	}
	return false
}
