package admin_agent

import (
	"context"
	"fmt"
	"time"

	"jnc-server/app/main/api/internal/svc"
	"jnc-server/app/main/api/internal/types"
	"jnc-server/common/globalkey"

	"github.com/zeromicro/go-zero/core/logx"
)

type AdminGetOrderTrendsLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewAdminGetOrderTrendsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetOrderTrendsLogic {
	return &AdminGetOrderTrendsLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminGetOrderTrendsLogic) AdminGetOrderTrends(req *types.AdminGetOrderTrendsReq) (resp *types.AdminGetOrderTrendsResp, err error) {
	// 1. Parse date parameters with default to last 30 days
	var startDate, endDate time.Time

	if req.StartDate != "" {
		startDate, err = time.Parse("2006-01-02", req.StartDate)
		if err != nil {
			return nil, fmt.Errorf("invalid start_date format: %v", err)
		}
	} else {
		// Default to 30 days ago
		startDate = time.Now().AddDate(0, 0, -30)
	}

	if req.EndDate != "" {
		endDate, err = time.Parse("2006-01-02", req.EndDate)
		if err != nil {
			return nil, fmt.Errorf("invalid end_date format: %v", err)
		}
		// Set end date to end of day
		endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 0, time.Local)
	} else {
		// Default to today
		endDate = time.Now()
	}

	// Ensure start date is before end date
	if startDate.After(endDate) {
		return nil, fmt.Errorf("start_date must be before end_date")
	}

	// 2. Query all commissions in date range
	builder := l.svcCtx.AgentCommissionModel.SelectBuilder()
	builder = builder.Where("del_state = ?", globalkey.DelStateNo)
	builder = builder.Where("create_time >= ?", startDate)
	builder = builder.Where("create_time <= ?", endDate)

	commissions, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, builder, "")
	if err != nil {
		return nil, fmt.Errorf("failed to query commissions: %v", err)
	}

	// 3. Group by date in Go
	dateMap := make(map[string]*struct {
		Amount float64
		Count  int64
	})

	for _, commission := range commissions {
		date := commission.CreateTime.Format("2006-01-02")
		if _, exists := dateMap[date]; !exists {
			dateMap[date] = &struct {
				Amount float64
				Count  int64
			}{}
		}
		dateMap[date].Amount += commission.Amount
		dateMap[date].Count++
	}

	// 4. Build sorted response
	dates := make([]string, 0, len(dateMap))
	amounts := make([]float64, 0, len(dateMap))
	counts := make([]int64, 0, len(dateMap))

	// Sort dates
	sortedDates := make([]string, 0, len(dateMap))
	for date := range dateMap {
		sortedDates = append(sortedDates, date)
	}

	// Simple bubble sort (can be optimized with sort package)
	for i := 0; i < len(sortedDates); i++ {
		for j := i + 1; j < len(sortedDates); j++ {
			if sortedDates[i] > sortedDates[j] {
				sortedDates[i], sortedDates[j] = sortedDates[j], sortedDates[i]
			}
		}
	}

	for _, date := range sortedDates {
		dates = append(dates, date)
		amounts = append(amounts, dateMap[date].Amount)
		counts = append(counts, dateMap[date].Count)
	}

	return &types.AdminGetOrderTrendsResp{
		Dates:   dates,
		Amounts: amounts,
		Counts:  counts,
	}, nil
}
