package biz

import (
	"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"
)

type AdviceSkillBiz struct {
	AdvicerTalkSkillMongo *mongo_model.AdvicerTalkSkillMongo
	mongo                 *pkg.Mongo
}

func NewAdviceSkillBiz(
	advicerTalkSkillMongo *mongo_model.AdvicerTalkSkillMongo,
	mongo *pkg.Mongo,
) *AdviceSkillBiz {
	return &AdviceSkillBiz{
		AdvicerTalkSkillMongo: advicerTalkSkillMongo,
		mongo:                 mongo,
	}
}

func (a *AdviceSkillBiz) VersionAdd(ctx context.Context, param *entitys.AdvicerTalkSkillAddReq) (id interface{}, err error) {

	res, err := a.mongo.Co(a.AdvicerTalkSkillMongo).InsertOne(ctx, &mongo_model.AdvicerTalkSkillMongo{
		ProjectId:           param.ProjectId,
		AdvicerId:           param.AdvicerId,
		Desc:                param.Desc,
		NeedsMining:         param.NeedsMining,
		PainPointResponse:   param.PainPointResponse,
		ValueBuilding:       param.ValueBuilding,
		ClosingTechniques:   param.ClosingTechniques,
		CommunicationRhythm: param.CommunicationRhythm,
		LastUpdateTime:      time.Now(),
	})
	if err != nil {
		return nil, err
	}
	return res.InsertedID, err
}

func (a *AdviceSkillBiz) VersionUpdate(ctx context.Context, param *entitys.AdvicerTalkSkillUpdateReq) (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.AdvicerTalkSkillMongo{
			AdvicerId:           param.AdvicerId,
			ProjectId:           param.ProjectId,
			Desc:                param.Desc,
			NeedsMining:         param.NeedsMining,
			PainPointResponse:   param.PainPointResponse,
			ValueBuilding:       param.ValueBuilding,
			ClosingTechniques:   param.ClosingTechniques,
			CommunicationRhythm: param.CommunicationRhythm,
			LastUpdateTime:      time.Now(),
		},
	}
	res := a.mongo.Co(a.AdvicerTalkSkillMongo).FindOneAndUpdate(ctx, filter, update)
	return res.Err()
}

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

	if param.ProjectId != 0 {
		filter["projectId"] = param.ProjectId
	}

	// 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.Desc) != 0 {
		// 正确的方式：指定字段名
		filter["desc"] = bson.M{
			"$regex": primitive.Regex{
				Pattern: param.Desc,
				Options: "i",
			},
		}
	}

	cursor, err := a.mongo.Co(a.AdvicerTalkSkillMongo).Find(ctx, filter)
	if err != nil {
		return nil, err
	}
	// 遍历结果
	for cursor.Next(ctx) {
		var advicerVersion mongo_model.AdvicerTalkSkillMongo
		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 *AdviceSkillBiz) VersionDel(ctx context.Context, param *entitys.AdvicerTalkSkillDelReq) (err error) {
	filter := bson.M{}

	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.AdvicerTalkSkillMongo).DeleteOne(ctx, filter)

	return err
}

func (a *AdviceSkillBiz) Info(ctx context.Context, param *entitys.AdvicerTalkSkillInfoReq) (info mongo_model.AdvicerTalkSkillMongo, 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.AdvicerTalkSkillMongo).FindOne(ctx, filter)
	if res.Err() != nil {
		return info, err
	}
	// 遍历结果

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

	return info, nil

}
