package merchant

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/duke-git/lancet/v2/pointer"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/option"
	"kami/internal/service"
	"kami/utility/cache"
	"kami/utility/utils"
	"time"

	"kami/api/merchant/v1"
)

func (c *ControllerV1) OrderQuerySummary(ctx context.Context, req *v1.OrderQuerySummaryReq) (res *v1.OrderQuerySummaryRes, err error) {
	res = &v1.OrderQuerySummaryRes{}
	record := make([]*v1.OrderQueryRecord, 0)

	orderInfo, err := service.OrderSummary().GetOneById(ctx, req.MerchantOrderNo)
	err = utils.HandleNoRowsError(err)
	if err != nil || pointer.IsNil(orderInfo) || orderInfo.Id == 0 {
		return
	}

	// 添加订单信息
	if orderInfo.PayTime != nil {
		record = append(record, &v1.OrderQueryRecord{
			CreatedAt: orderInfo.CreateTime,
			Operation: "拉取订单",
		})
		record = append(record, &v1.OrderQueryRecord{
			CreatedAt: orderInfo.PayTime,
			Operation: "用户提交卡密",
		})
	} else {
		record = append(record, &v1.OrderQueryRecord{
			CreatedAt: orderInfo.CreateTime,
			Operation: "拉取订单，未上传卡密",
		})
	}
	if orderInfo.IsBlock == 1 {
		record = append(record, &v1.OrderQueryRecord{
			CreatedAt: orderInfo.UpdateTime,
			Operation: "订单被禁用",
		})
	}
	appleRecord := queryAppleCard(ctx, req.MerchantOrderNo)
	record = append(record, appleRecord...)
	redeemRecord := queryRedeemCard(ctx, req.MerchantOrderNo)
	record = append(record, redeemRecord...)
	if len(record) > 0 {
		r := ghttp.RequestFromCtx(ctx)
		if r != nil {
			// 检查缓存
			cacheKey := fmt.Sprintf("order_summary:%s:%d", req.MerchantOrderNo, len(record))
			cachedResult, err := cache.NewCache().Get(ctx, cacheKey)
			if err == nil && cachedResult != nil && !cachedResult.IsNil() {
				// 如果有缓存，直接返回缓存结果
				cachedData := cachedResult.String()
				sendCachedResult(r, cachedData)
				return nil, nil
			}

			// 如果没有缓存或缓存已过期，则查询AI并缓存结果
			queryAppleResult(ctx, r, record, cacheKey)
			return nil, nil
		}
	}
	return
}

// sendCachedResult 发送缓存的结果
func sendCachedResult(r *ghttp.Request, cachedData string) {
	// 设置 SSE 响应头
	r.Response.Header().Set("Content-Type", "text/event-stream")
	r.Response.Header().Set("Cache-Control", "no-cache")
	r.Response.Header().Set("Connection", "keep-alive")

	// 发送缓存数据
	eventData := map[string]interface{}{
		"content": cachedData,
	}
	dataBytes, _ := json.Marshal(eventData)
	r.Response.Write([]byte(fmt.Sprintf("data: %s\n\n", string(dataBytes))))
	r.Response.Flush()
}

// queryAppleResult 通过 SSE 流式返回 AI 总结结果
func queryAppleResult(ctx context.Context, r *ghttp.Request, record []*v1.OrderQueryRecord, cacheKey string) {
	var copyRecord []*struct {
		Operation string
		Remark    string
		CreatedAt *gtime.Time
	}
	for _, queryRecord := range record {
		copyRecord = append(copyRecord, &struct {
			Operation string
			Remark    string
			CreatedAt *gtime.Time
		}{
			Operation: queryRecord.Operation,
			Remark:    queryRecord.Remark,
			CreatedAt: queryRecord.CreatedAt,
		})
	}
	recordStr, _ := json.Marshal(copyRecord)

	// 设置 SSE 响应头
	r.Response.Header().Set("Content-Type", "text/event-stream")
	r.Response.Header().Set("Cache-Control", "no-cache")
	r.Response.Header().Set("Connection", "keep-alive")

	client := openai.NewClient(
		option.WithAPIKey("sk-jYRlGtXAJ3Q82TS_FxWLFX6wn_VubNnyCtfxYZYP32ccqfQaGwQJHMq5I7k"),
		option.WithBaseURL("https://hk.uniapi.io/v1"),
	)

	// 使用流式 API 获取结果
	stream := client.Chat.Completions.NewStreaming(ctx, openai.ChatCompletionNewParams{
		Messages: []openai.ChatCompletionMessageParamUnion{
			openai.UserMessage(fmt.Sprintf("%s\n只生成结论，不需要建议，用中文回复", string(recordStr))),
		},
		Model: "deepseek-v3.2-exp",
	})

	// 收集完整的响应内容
	var fullContent string

	// 逐块发送流式数据
	for stream.Next() {
		chunk := stream.Current()
		if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
			content := chunk.Choices[0].Delta.Content
			fullContent += content
			// 创建 SSE 格式的数据
			eventData := map[string]interface{}{
				"content": content,
			}
			dataBytes, _ := json.Marshal(eventData)
			r.Response.Write([]byte(fmt.Sprintf("data: %s\n\n", string(dataBytes))))
			// 使用 GoFrame 内置的 Flush 方法立即刷新缓冲区
			r.Response.Flush()
		}
	}

	// 缓存完整结果24小时
	if fullContent != "" {
		_ = cache.NewCache().Set(ctx, cacheKey, fullContent, time.Hour*24)
	}
}
