package ii

import (
	"fmt"

	"git.simanc.com/software/golib/v4/features/mo"
)

// ArgLookup 检查错误并返回 ItemInfo.Fields 中已配置的 Lookup 过滤器
// 当 Lookup 为有效配置时, 检查 Lookup.From 是否存在于 Items 内以及检查 FieldInfo.Fields 内的字段是否存在于该 ItemInfo 内
func (c *ItemInfo) ArgLookup(items Items) ([]mo.D, error) {
	lookFilter := make([]mo.D, 0)
	for _, field := range c.Fields {
		for _, lookup := range field.Lookup {
			if !lookup.Valid() {
				continue
			}
			info, ok := items.Has(c.ForkDb(lookup.From))
			if !ok {
				return nil, fmt.Errorf("iteminfo: %s.%s.Lookup.From: %s: item not found", c.Name, field.Name, lookup.From)
			}
			if _, ok = info.Field(lookup.ForeignField); !ok {
				return nil, fmt.Errorf("iteminfo: %s.%s.Lookup.Foreign: %s: not found in iteminfo: %s", c.Name, field.Name, lookup.ForeignField, info.Name)
			}
			lookFilter = append(lookFilter, field.ArgLookup(&lookup).Pipeline())
		}
	}
	return lookFilter, nil
}

// ArgSet 检查错误并返回 ItemInfo.Fields 中已配置的 Set 聚合操作
// 当 Set 为有效配置时, 检查 Set.Name 是否存在于 ItemInfo 内
func (c *ItemInfo) ArgSet() ([]mo.D, error) {
	sets := make([]mo.D, 0)
	for _, field := range c.Fields {
		// if !field.HasSet() {
		// 	continue
		// }
		for _, set := range field.Set {
			switch set.OP {
			case mo.OptSum:
				sets = append(sets, field.ArgSet().Pipeline())
			default:
				continue
			}
		}
	}
	return sets, nil
}

func (c *ItemInfo) Aggregation(items Items) ([]mo.D, error) {
	arg := make([]mo.D, 0)
	lookup, err := c.ArgLookup(items)
	if err != nil {
		return nil, err
	}
	arg = append(arg, lookup...)
	set, err := c.ArgSet()
	if err != nil {
		return nil, err
	}
	arg = append(arg, set...)
	return arg, nil
}
