package biz

import (
	"ai_scheduler/internal/data/impl"
	"ai_scheduler/internal/data/model"
	"ai_scheduler/internal/data/mongo_model"
	"ai_scheduler/internal/entitys"
	"ai_scheduler/internal/pkg"
	"errors"
	"fmt"
	"time"

	"context"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"xorm.io/builder"
)

type AdviceAdvicerBiz struct {
	advicerImpl         *impl.AdviceAdvicerImpl
	advicerVersionMongo *mongo_model.AdvicerVersionMongo
	mongo               *pkg.Mongo
}

func NewAdviceAdvicerBiz(
	advicerImpl *impl.AdviceAdvicerImpl,
	advicerVersionMongo *mongo_model.AdvicerVersionMongo,
	mongo *pkg.Mongo,
) *AdviceAdvicerBiz {
	return &AdviceAdvicerBiz{
		advicerImpl:         advicerImpl,
		advicerVersionMongo: advicerVersionMongo,
		mongo:               mongo,
	}
}

func (a *AdviceAdvicerBiz) Update(ctx context.Context, data *entitys.AdvicerInitReq) (int32, error) {
	birth, err := time.Parse("2006-01-02", data.Birth)
	if err != nil {
		return 0, err
	}
	param := &model.AiAdviceAdvicer{
		AdvicerID:    data.AdvicerID,
		ProjectID:    data.ProjectID,
		Name:         data.Name,
		Birth:        birth,
		Gender:       data.Gender,
		WorkingYears: data.WorkingYears,
	}
	if param.AdvicerID == 0 {
		err = a.advicerImpl.AddWithData(param)
	} else {
		cond := builder.NewCond()
		cond = cond.And(builder.Eq{"advicer_id": param.AdvicerID})
		err = a.advicerImpl.UpdateByCond(&cond, param)
	}
	return param.AdvicerID, err
}

func (a *AdviceAdvicerBiz) List(ctx context.Context, data *entitys.AdvicerListReq) ([]map[string]interface{}, error) {

	cond := builder.NewCond()
	cond = cond.And(builder.Eq{"project_id": data.ProjectId})
	list, err := a.advicerImpl.GetRange(&cond)
	return list, err
}

func (a *AdviceAdvicerBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerVersionAddReq) (id interface{}, err error) {
	cond := builder.NewCond()
	cond = cond.And(builder.Eq{"advicer_id": param.AdvicerID})
	_, err = a.advicerImpl.GetOneBySearch(&cond)
	if err != nil {
		return 0, errors.New("顾问不存在")
	}
	res, err := a.mongo.Co(a.advicerVersionMongo).InsertOne(ctx, &mongo_model.AdvicerVersionMongo{
		AdvicerId:          param.AdvicerID,
		VersionDesc:        param.VersionDesc,
		DialectFeatures:    param.DialectFeatures,
		SentencePatterns:   param.SentencePatterns,
		ToneTags:           param.ToneTags,
		PersonalityTags:    param.PersonalityTags,
		SignatureDialogues: param.SignatureDialogues,
		LastUpdateTime:     time.Now(),
	})
	if err != nil {
		return nil, err
	}
	return res.InsertedID, err
}

func (a *AdviceAdvicerBiz) VersionUpdate(ctx context.Context, param *entitys.AdvicerVersionUpdateReq) (err error) {
	filter := bson.M{}
	if len(param.Id) == 0 {
		return errors.New("ID不能为空")
	}
	objectID, err := primitive.ObjectIDFromHex(param.Id)
	if err != nil {
		return fmt.Errorf("ID转换失败: %w", err)
	}
	filter["_id"] = objectID
	update := bson.M{
		"$set": &mongo_model.AdvicerVersionMongo{
			AdvicerId:          param.AdvicerID,
			VersionDesc:        param.VersionDesc,
			DialectFeatures:    param.DialectFeatures,
			SentencePatterns:   param.SentencePatterns,
			ToneTags:           param.ToneTags,
			PersonalityTags:    param.PersonalityTags,
			SignatureDialogues: param.SignatureDialogues,
			LastUpdateTime:     time.Now(),
		},
	}
	res := a.mongo.Co(a.advicerVersionMongo).FindOneAndUpdate(ctx, filter, update)

	return res.Err()
}

func (a *AdviceAdvicerBiz) VersionList(ctx context.Context, param *entitys.AdvicerVersionListReq) (list []mongo_model.AdvicerVersionMongo, err error) {
	filter := bson.M{}
	// 1. advicer_id 条件
	if param.AdvicerId != 0 {
		filter["advicerId"] = param.AdvicerId
	}

	// 2. _id 条件
	if len(param.Id) != 0 {
		objectID, err := primitive.ObjectIDFromHex(param.Id)
		if err != nil {
			return nil, fmt.Errorf("ID转换失败: %w", err)
		}
		filter["_id"] = objectID
	}

	// 3. version_desc 模糊查询
	if len(param.VersionDesc) != 0 {
		// 正确的方式：指定字段名
		filter["versionDesc"] = bson.M{
			"$regex": primitive.Regex{
				Pattern: param.VersionDesc,
				Options: "i",
			},
		}
	}

	cursor, err := a.mongo.Co(a.advicerVersionMongo).Find(ctx, filter)
	if err != nil {
		return nil, err
	}
	// 遍历结果
	for cursor.Next(ctx) {
		var advicerVersion mongo_model.AdvicerVersionMongo
		if err := cursor.Decode(&advicerVersion); err != nil {
			return nil, err
		}
		list = append(list, advicerVersion)
	}

	if err := cursor.Err(); err != nil {
		return nil, err
	}
	return list, err
}

func (a *AdviceAdvicerBiz) VersionDel(ctx context.Context, param *entitys.AdvicerVersionDelReq) (err error) {
	filter := bson.M{}
	// 1. advicer_id 条件

	if len(param.Id) != 0 {
		objectID, err := primitive.ObjectIDFromHex(param.Id)
		if err != nil {
			return fmt.Errorf("ID转换失败: %w", err)
		}
		filter["_id"] = objectID
	}

	_, err = a.mongo.Co(a.advicerVersionMongo).DeleteOne(ctx, filter)

	return err
}

func (a *AdviceAdvicerBiz) VersionInfo(ctx context.Context, param *entitys.AdvicerVersionInfoReq) (info mongo_model.AdvicerVersionMongo, err error) {
	filter := bson.M{}
	if len(param.Id) != 0 {
		objectID, err := primitive.ObjectIDFromHex(param.Id)
		if err != nil {
			return info, fmt.Errorf("ID转换失败: %w", err)

		}
		filter["_id"] = objectID
	}

	res := a.mongo.Co(a.advicerVersionMongo).FindOne(ctx, filter)
	if res.Err() != nil {
		return info, res.Err()
	}

	if err := res.Decode(&info); err != nil {
		return info, err
	}
	return info, nil
}

func (a *AdviceAdvicerBiz) AdvicerInfo(ctx context.Context, param *entitys.AdvicerInfoReq) (info model.AiAdviceAdvicer, err error) {
	cond := builder.NewCond()
	cond = cond.And(builder.Eq{"advicer_id": param.AdvicerID})

	err = a.advicerImpl.GetOneBySearchToStrut(&cond, &info)
	return
}
