package biz

import (
	"ai_scheduler/internal/biz/llm_service/third_party"
	dbmodel "ai_scheduler/internal/data/model"
	"ai_scheduler/internal/data/mongo_model"
	"ai_scheduler/internal/entitys"
	"ai_scheduler/internal/pkg"
	"context"
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model"
	"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model/responses"
	"github.com/volcengine/volcengine-go-sdk/volcengine"
)

type AdviceFileBiz struct {
	hsyq *third_party.Hsyq
}

func NewAdviceFileBiz(hsyq *third_party.Hsyq) *AdviceFileBiz {
	return &AdviceFileBiz{
		hsyq: hsyq,
	}
}

var DataMap = map[string]mongo_model.AdviceData{
	"dialectFeatures":       &mongo_model.DialectFeatures{},
	"sentencePatterns":      &mongo_model.SentencePatterns{},
	"personalityTags":       &mongo_model.PersonalityTags{},
	"toneTags":              &mongo_model.ToneTags{},
	"signatureDialogues":    &mongo_model.SignatureDialogues{},
	"regionValue":           &mongo_model.RegionValue{},
	"competitionComparison": &mongo_model.CompetitionComparison{},
	"coreSellingPoints":     &mongo_model.CoreSellingPoints{},
	"supportingFacilities":  &mongo_model.SupportingFacilities{},
	"developerBacking":      &mongo_model.DeveloperBacking{},
	"needsMining":           &mongo_model.NeedsMining{},
	"painPointResponse":     &mongo_model.PainPointResponse{},
	"valueBuilding":         &mongo_model.ValueBuilding{},
	"closingTechniques":     &mongo_model.ClosingTechniques{},
	"communicationRhythm":   &mongo_model.CommunicationRhythm{},
	"customer":              &mongo_model.Customer{},
}

func (a *AdviceFileBiz) WordAna(ctx context.Context, wordContent string, projectInfo *entitys.AdvicerProjectInfoRes) (map[mongo_model.AdviceRole]map[string]mongo_model.AdviceData, error) {
	if len(projectInfo.ModelInfo.FileModel) == 0 {
		return nil, fmt.Errorf("项目文件模型信息缺失")
	}
	timeSte := time.Now().Format("200601021504")
	dir := "./cache/" + timeSte
	os.Mkdir(dir, 0755)
	//获取示例
	examples := a.getAllExamples()

	//构建提示词
	prompt := a.buildSimplePrompt(wordContent, examples)
	os.WriteFile(dir+"/requset.json", []byte(prompt), 0644)

	//llm提取信息
	anaContent, err := a.callLlm2(ctx, prompt, &projectInfo.ModelInfo)
	if err != nil {
		return nil, err
	}
	os.WriteFile(dir+"/res.json", []byte(anaContent), 0644)

	//格式整理
	data, err := a.parseResponse(ctx, []byte(anaContent))
	if err != nil {
		return nil, err
	}

	//组装数据
	resData := a.cateData(data)
	os.WriteFile("./cache/"+timeSte+"/extracted.json", pkg.JsonByteIgonErr(resData), 0644)
	return resData, err
}

func (a *AdviceFileBiz) cateData(data map[string]mongo_model.AdviceData) map[mongo_model.AdviceRole]map[string]mongo_model.AdviceData {
	var res = make(map[mongo_model.AdviceRole]map[string]mongo_model.AdviceData)
	for k, v := range data {
		if _, ok := res[v.Role()]; !ok {
			res[v.Role()] = make(map[string]mongo_model.AdviceData)
		}
		res[v.Role()][k] = v
	}
	return res
}

func (a *AdviceFileBiz) parseResponse(ctx context.Context, responseByte []byte) (resultOutPut map[string]mongo_model.AdviceData, err error) {
	//只尝试修复一次
	//if isValid := json.Valid(responseByte); !isValid {
	//
	//	if err != nil {
	//		return nil, fmt.Errorf("json格式错误，修复失败:%s", err.Error())
	//	}
	//}
	if isValid := json.Valid(responseByte); !isValid {
		return nil, fmt.Errorf("json格式错误")
	}

	var (
		result map[string]interface{}
	)

	resultOutPut = make(map[string]mongo_model.AdviceData)
	if err = json.Unmarshal(responseByte, &result); err != nil {

		return
	}
	for k, v := range result {
		if _, ok := DataMap[k]; !ok {
			return
		}
		var vbyte []byte
		if vbyte, err = json.Marshal(v); err != nil {
			return
		}
		newData := DataMap[k].Copy()

		if err = json.Unmarshal(vbyte, newData); err != nil {
			return
		}
		resultOutPut[k] = newData
	}

	return
}

//func (a *AdviceFileBiz) fixJson(ctx context.Context, json []byte) ([]byte, error) {
//	prompt := "你是一个专业的JSON修复专家。请帮我修复以下错误的JSON格式。\n\n要求：\n1. 保持原有数据的结构和内容不变\n2. 修复JSON语法错误\n3. 输出格式化的正确JSON\n4. 简要说明修复了哪些问题\n\n错误的JSON：\n" + string(json) + "\n\n请直接输出修复后的JSON。"
//	call, err := a.callLlm(ctx, prompt, jsonModel)
//	if err != nil {
//		return nil, err
//	}
//
//	return []byte(call), nil
//}

func (a *AdviceFileBiz) callLlm(ctx context.Context, prompt string, modelInfo *dbmodel.AiAdviceModelSup) (string, error) {
	var message = make([]*model.ChatCompletionMessage, 1)
	message[0] = &model.ChatCompletionMessage{
		Role: model.ChatMessageRoleUser,
		Content: &model.ChatCompletionMessageContent{
			StringValue: volcengine.String(prompt),
		},
	}
	res, err := a.hsyq.Chat(ctx, modelInfo.Key, modelInfo.FileModel, message)
	if err != nil {
		return "", err
	}

	return *res.Choices[0].Message.Content.StringValue, nil
}

func (a *AdviceFileBiz) callLlm2(ctx context.Context, prompt string, modelInfo *dbmodel.AiAdviceModelSup) (string, error) {
	var message = make([]*responses.InputItem, 3)
	message[0] = &responses.InputItem{
		Union: &responses.InputItem_EasyMessage{
			EasyMessage: &responses.ItemEasyMessage{
				Role:    responses.MessageRole_system,
				Content: &responses.MessageContent{Union: &responses.MessageContent_StringValue{StringValue: prompt}},
			},
		},
	}
	res, err := a.hsyq.CreateResponse(ctx, modelInfo.Key, modelInfo.FileModel, message, "", false)
	if err != nil {
		return "", err
	}

	return res.Output[0].GetOutputMessage().Content[0].GetText().GetText(), nil
}

func (a *AdviceFileBiz) getAllExamples() map[string]mongo_model.AdviceData {
	return DataMap
}

func (a *AdviceFileBiz) buildSimplePrompt(wordContent string, examples map[string]mongo_model.AdviceData) string {
	// 最简单的提示词模板
	template := `分析以下房地产销售对话，按指定格式提取信息：

对话内容：
%s

请按照以下` + fmt.Sprintf("%d", len(examples)) + `个格式生成JSON数据，key为格式名称，value为对应值：

%s

输出要求：
1. 所有内容必须严格基于提供的对话原文，不得编造(重要！)
2. 每个结构体一个JSON对象
3. 严格按照示例格式
4. 将上述生成的` + fmt.Sprintf("%d", len(examples)) + `个JSON对象,json不需要有可读性,不要有特殊符号，比如"\n",用map[string]json来包裹所有json对象：{"SupportingFacilities":{...},"SignatureDialogues":[{...},{...}]}`
	// 构建格式部分
	var formats strings.Builder
	for name, example := range examples {
		formats.WriteString(fmt.Sprintf("=== %s (%s:%s)===\n示例：%s\n\n", name, mongo_model.RoleDesc[example.Role()], example.Desc(), example.Example()))
	}

	return fmt.Sprintf(template, wordContent, formats.String())
}
