package queries

import (
	"context"
	"database/sql"
	"fmt"
	"strings"
)

type Last10AvgPurchasePriceRow struct {
	ItemCode       string
	CurrencyCode   string
	SampleCount    int
	AvgDocPrice    float64
	MinInvoiceDate sql.NullString
	MaxInvoiceDate sql.NullString
}

// LookupLast10AvgPurchasePriceByItemCodes reads from dbo.cache_last10_avg_purchase_price (Nebim/V3 MSSQL).
// It is designed to be used in hot paths (save) where live invoice scans are too slow.
func LookupLast10AvgPurchasePriceByItemCodes(ctx context.Context, mssqlDB *sql.DB, itemCodes []string) ([]Last10AvgPurchasePriceRow, error) {
	if mssqlDB == nil {
		return nil, fmt.Errorf("mssql db is nil")
	}
	codes := make([]string, 0, len(itemCodes))
	seen := map[string]struct{}{}
	for _, c := range itemCodes {
		c = strings.TrimSpace(c)
		if c == "" {
			continue
		}
		if _, ok := seen[c]; ok {
			continue
		}
		seen[c] = struct{}{}
		codes = append(codes, c)
	}
	if len(codes) == 0 {
		return []Last10AvgPurchasePriceRow{}, nil
	}

	valParts := make([]string, 0, len(codes))
	args := make([]any, 0, len(codes))
	for i, code := range codes {
		valParts = append(valParts, fmt.Sprintf("(@p%d)", i+1))
		args = append(args, code)
	}

	sqlText := fmt.Sprintf(`
WITH C AS (
  SELECT LTRIM(RTRIM(V.code)) AS ItemCode
  FROM (VALUES %s) AS V(code)
)
SELECT
  T.ItemCode,
  T.Doc_CurrencyCode,
  T.sample_count,
  T.avg_doc_price,
  CONVERT(varchar(10), T.min_invoice_date, 23) AS min_invoice_date,
  CONVERT(varchar(10), T.max_invoice_date, 23) AS max_invoice_date
FROM dbo.cache_last10_avg_purchase_price T
INNER JOIN C
  ON C.ItemCode = T.ItemCode
`, strings.Join(valParts, ","))

	rows, err := mssqlDB.QueryContext(ctx, sqlText, args...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	out := make([]Last10AvgPurchasePriceRow, 0, len(codes))
	for rows.Next() {
		var r Last10AvgPurchasePriceRow
		if err := rows.Scan(&r.ItemCode, &r.CurrencyCode, &r.SampleCount, &r.AvgDocPrice, &r.MinInvoiceDate, &r.MaxInvoiceDate); err != nil {
			return nil, err
		}
		r.ItemCode = strings.TrimSpace(r.ItemCode)
		r.CurrencyCode = strings.TrimSpace(strings.ToUpper(r.CurrencyCode))
		out = append(out, r)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return out, nil
}
