package store

import "context"

// 评测观测查询（admin「自动评测」页做实用；此前该页纯 mock）。全平台口径 → WithoutTenant。
// 注：评测的「纠偏前后全文轨迹」后端未持久化，只存了 Reason(评语)/Corrected(是否已纠偏采纳)/
// 各维度分，故错题本展示这些真数据，不含编造的 before/after 对照。

// EvalDay 是评测趋势按天一行。
type EvalDay struct {
	Day         string  `json:"day"`          // YYYYMMDD
	AvgOverall  float64 `json:"avg_overall"`  // 当日综合分均值 [0,1]
	AvgFaithful float64 `json:"avg_faithful"` // 当日忠实度均值（仅计有来源的评测）
	Count       int64   `json:"count"`
	PoorCount   int64   `json:"poor_count"` // 当日 poor 级条数（幻觉/低质趋势）
}

// EvalTrend 按天聚合评测（from/to 为 YYYYMMDD）。avg_faithful 只算有检索来源的评测（sources>0），
// 无来源的忠实度恒 0 会把均值压低失真。
func (p *Postgres) EvalTrend(ctx context.Context, from, to string) []EvalDay {
	if p.db == nil {
		return nil
	}
	var out []EvalDay
	p.db.WithContext(ctx).Model(&Eval{}).
		Select("to_char(created_at,'YYYYMMDD') as day, "+
			"avg(overall) as avg_overall, "+
			"avg(case when sources > 0 then faithful end) as avg_faithful, "+
			"count(*) as count, "+
			"count(case when level = 'poor' then 1 end) as poor_count").
		Where("to_char(created_at,'YYYYMMDD') >= ? AND to_char(created_at,'YYYYMMDD') <= ?", from, to).
		Group("day").Order("day").Scan(&out)
	return out
}

// EvalSummary 是评测总览计数。
type EvalSummary struct {
	Total      int64   `json:"total"`
	OK         int64   `json:"ok"`
	Warn       int64   `json:"warn"`
	Poor       int64   `json:"poor"`
	Corrected  int64   `json:"corrected"`   // 经低分自动纠偏重生成后采纳的条数（恒温器闭环成效）
	AvgOverall float64 `json:"avg_overall"` // 区间综合分均值
}

// EvalSummaryFor 区间内评测计数（from/to 为 YYYYMMDD）。
func (p *Postgres) EvalSummaryFor(ctx context.Context, from, to string) EvalSummary {
	var s EvalSummary
	if p.db == nil {
		return s
	}
	p.db.WithContext(ctx).Model(&Eval{}).
		Select("count(*) as total, "+
			"count(case when level='ok' then 1 end) as ok, "+
			"count(case when level='warn' then 1 end) as warn, "+
			"count(case when level='poor' then 1 end) as poor, "+
			"count(case when corrected then 1 end) as corrected, "+
			"coalesce(avg(overall),0) as avg_overall").
		Where("to_char(created_at,'YYYYMMDD') >= ? AND to_char(created_at,'YYYYMMDD') <= ?", from, to).
		Scan(&s)
	return s
}

// PoorEval 是错题本一行（低分评测 + 评语 + 纠偏标记；带租户名免前端二次查）。
type PoorEval struct {
	TaskID     string  `json:"task_id"`
	TenantName string  `json:"tenant_name"`
	Owner      string  `json:"owner"`
	Overall    float64 `json:"overall"`
	Rule       float64 `json:"rule"`
	LLM        float64 `json:"llm"`
	Faithful   float64 `json:"faithful"`
	Level      string  `json:"level"`
	Reason     string  `json:"reason"`
	Sources    int     `json:"sources"`
	Corrected  bool    `json:"corrected"`
	CreatedAt  string  `json:"created_at"`
}

// PoorEvals 最近的低分评测（level=poor/warn，错题本）。
func (p *Postgres) PoorEvals(ctx context.Context, limit int) []PoorEval {
	if p.db == nil {
		return nil
	}
	if limit <= 0 || limit > 100 {
		limit = 30
	}
	var out []PoorEval
	p.db.WithContext(ctx).Table("sundynix_eval e").
		Select("e.task_id, coalesce(t.name,'') as tenant_name, e.owner, e.overall, e.rule, e.llm, "+
			"e.faithful, e.level, e.reason, e.sources, e.corrected, "+
			"to_char(e.created_at,'YYYY-MM-DD HH24:MI') as created_at").
		Joins("left join sundynix_tenant t on t.id = e.tenant_id").
		Where("e.level in ('poor','warn') AND e.deleted_at IS NULL").
		Order("e.created_at desc").Limit(limit).Scan(&out)
	return out
}
