package plant

import (
	"errors"
	"sundynix-go/global"
	common "sundynix-go/model/commom/request"
	"sundynix-go/model/plant"
	plantReq "sundynix-go/model/plant/request"
	"sundynix-go/model/system"

	"gorm.io/gorm"
)

var aiRagService = AiRagService{}

type WikiService struct{}

var WikiServiceApp = new(WikiClassService)

// CreateWiki 创建百科
func (s *WikiService) CreateWiki(req plantReq.CreateWiki) error {
	err := global.DB.Transaction(func(tx *gorm.DB) error {
		//1.先模糊查询name是否存在 如果存在 则返回错误
		if !errors.Is(tx.Where("name like ?", "%"+req.Name+"%").First(&plant.Wiki{}).Error, gorm.ErrRecordNotFound) {
			return errors.New("植物已经存在")
		}

		//2.图片
		var ossList []*system.Oss
		err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
		if err != nil {
			return err
		}
		//3. 分类
		var classes []*plant.Class
		err = tx.Where("id in ?", req.ClassIds).Find(&classes).Error
		if err != nil {
			return err
		}
		//4. 相关的植物
		var relatedWiki []*plant.Wiki
		err = tx.Where("id in ?", req.RelatedWikiIds).Find(&relatedWiki).Error
		if err != nil {
			return err
		}
		//6.保存数据
		wiki := plant.Wiki{
			IsHot:              req.IsHot,
			Name:               req.Name,
			LatinName:          req.LatinName,
			Aliases:            req.Aliases,
			Difficulty:         req.Difficulty,
			DistributionArea:   req.DistributionArea,
			Stem:               req.Stem,
			Fruit:              req.Fruit,
			Genus:              req.Genus,
			LifeCycle:          req.LifeCycle,
			GrowthHabit:        req.GrowthHabit,
			ReproductionMethod: req.ReproductionMethod,
			PestsDiseases:      req.PestsDiseases,
			LightIntensity:     req.LightIntensity,
			LightType:          req.LightType,
			OptimalTempPeriod:  req.OptimalTempPeriod,
			FoliageType:        req.FoliageType,
			FoliageColor:       req.FoliageColor,
			FoliageShape:       req.FoliageShape,
			Height:             req.Height,
			FloweringPeriod:    req.FloweringPeriod,
			FloweringColor:     req.FloweringColor,
			FloweringShape:     req.FloweringShape,
			FlowerDiameter:     req.FlowerDiameter,
		}
		err = tx.Create(&wiki).Error
		if err != nil {
			return err
		}
		//7.处理图片关系
		if len(ossList) > 0 {
			var relations []map[string]interface{}
			for _, oss := range ossList {
				relations = append(relations, map[string]interface{}{
					"wiki_id": wiki.Id,
					"oss_id":  oss.Id,
				})
			}
			err = tx.Table("sundynix_wiki_oss").Create(relations).Error
			if err != nil {
				return err
			}
		}
		//8.处理分类关系
		if len(classes) > 0 {
			var classRelations []map[string]interface{}
			for _, class := range classes {
				classRelations = append(classRelations, map[string]interface{}{
					"wiki_id":  wiki.Id,
					"class_id": class.Id,
				})
			}
			err = tx.Table("sundynix_wiki_class").Create(classRelations).Error
			if err != nil {
				return err
			}
		}
		//9.处理相关植物关系
		if len(relatedWiki) > 0 {
			var relatedWikiRelations []map[string]interface{}
			for _, item := range relatedWiki {
				relatedWikiRelations = append(relatedWikiRelations, map[string]interface{}{
					"wiki_id":         wiki.Id,
					"related_wiki_id": item.Id,
				})
			}
			err = tx.Table("sundynix_wiki_related").Create(relatedWikiRelations).Error
			if err != nil {
				return err
			}
		}

		return nil
	})
	if err == nil {
		// 异步同步到 Qdrant（事务提交后，wiki.Id 已可用）
		var created plant.Wiki
		if dbErr := global.DB.Where("name = ?", req.Name).First(&created).Error; dbErr == nil {
			aiRagService.SyncSingleWikiAsync(created.Id)
		}
	}
	return err
}

// UpdateWiki 修改百科
func (s *WikiService) UpdateWiki(req plantReq.UpdateWiki) error {
	updateData := map[string]interface{}{
		"name":                req.Name,
		"latin_name":          req.LatinName,
		"aliases":             req.Aliases,
		"difficulty":          req.Difficulty,
		"genus":               req.Genus,
		"distribution_area":   req.DistributionArea,
		"life_cycle":          req.LifeCycle,
		"growth_habit":        req.GrowthHabit,
		"pests_diseases":      req.PestsDiseases,
		"light_intensity":     req.LightIntensity,
		"light_type":          req.LightType,
		"optimal_temp_period": req.OptimalTempPeriod,
		"stem":                req.Stem,
		"fruit":               req.Fruit,
		"foliage_type":        req.FoliageType,
		"foliage_color":       req.FoliageColor,
		"foliage_shape":       req.FoliageShape,
		"height":              req.Height,
		"flowering_period":    req.FloweringPeriod,
		"flowering_color":     req.FloweringColor,
		"flowering_shape":     req.FloweringShape,
		"flower_diameter":     req.FlowerDiameter,
	}
	err := global.DB.Model(&plant.Wiki{}).Where("id = ?", req.Id).Updates(updateData).Error
	return err
}

// WikiPage 分页
func (s *WikiService) WikiPage(req plantReq.WikiPage, userId string) (list interface{}, total int64, err error) {
	limit := req.PageSize
	offset := req.PageSize * (req.Current - 1)
	db := global.DB.Model(&plant.Wiki{}).Preload("ImgList", func(db *gorm.DB) *gorm.DB {
		return db.Order("created_at desc")
	}).Preload("Classes", func(db *gorm.DB) *gorm.DB {
		return db.Order("created_at desc")
	})
	var wikis []plant.Wiki
	if req.Name != "" {
		db = db.Where("name like ?", "%"+req.Name+"%")
	}
	if req.IsHot != nil {
		db = db.Where("is_hot = ?", *req.IsHot)
	}
	if len(req.ClassIdIs) > 0 {
		db = db.Joins("inner join sundynix_wiki_class on sundynix_wiki_class.wiki_id = sundynix_wiki.id").
			Where("sundynix_wiki_class.class_id IN (?)", req.ClassIdIs)
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Order("is_hot desc,created_at desc").Find(&wikis).Error

	// 优化 N+1 查询
	var wikiIds []string
	for _, v := range wikis {
		wikiIds = append(wikiIds, v.Id)
	}
	//批量查询当前用户的收藏
	var stars []*plant.UserStar
	err = global.DB.Where("user_id = ? and wiki_id in ?", userId, wikiIds).Find(&stars).Error
	if err != nil {
		return
	}
	starsMap := make(map[string]bool)
	for _, v := range stars {
		starsMap[v.WikiId] = true
	}
	// 是否收藏
	for i := range wikis {
		if starsMap[wikis[i].Id] {
			wikis[i].HasStar = 1
		} else {
			wikis[i].HasStar = 0
		}
	}
	return wikis, total, err
}

// Detail 详情
func (s *WikiService) Detail(id, userId string) (w plant.Wiki, err error) {
	var wiki plant.Wiki
	err = global.DB.Where("id = ?", id).
		Preload("Classes", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Preload("ImgList", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Preload("RelatedWiki", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		First(&wiki).Error
	if err != nil {
		return
	}
	var stars []plant.UserStar
	err = global.DB.Where("user_id = ? and wiki_id = ?", userId, id).Find(&stars).Error
	if err != nil {
		return
	}
	if len(stars) > 0 {
		wiki.HasStar = 1
	}
	return wiki, nil
}

// StarWiki 收藏
func (s *WikiService) StarWiki(userId, wikiId, class string) error {
	if class == "1" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var wiki plant.Wiki
			err := tx.Where("id = ?", wikiId).First(&wiki).Error
			if err != nil {
				return err
			}
			//2.添加到我的收藏
			star := plant.UserStar{
				UserId: userId,
				Type:   1,
				WikiId: wikiId,
			}
			return tx.Create(&star).Error
		})
	} else if class == "2" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var star plant.UserStar
			err := tx.Where("wiki_id = ? and user_id = ?", wikiId, userId).First(&star).Error
			if err != nil {
				return err
			}
			//2.删除收藏
			return tx.Unscoped().Delete(&star).Error
		})
	}
	return nil
}

// UploadImg 上传图片
func (s *WikiService) UploadImg(req common.UploadOss) error {

	return global.DB.Transaction(func(tx *gorm.DB) error {
		var wiki plant.Wiki
		err := tx.Where("id = ?", req.Id).First(&wiki).Error
		if err != nil {
			return err
		}
		var ossList []system.Oss
		err = tx.Where("id in ?", req.OssIds).Find(&ossList).Error
		if err != nil {
			return err
		}
		var relations []map[string]interface{}
		for _, oss := range ossList {
			relations = append(relations, map[string]interface{}{
				"wiki_id": wiki.Id,
				"oss_id":  oss.Id,
			})
		}
		//3.添加关联关系（添加引用）
		return global.DB.Table("sundynix_wiki_oss").Create(relations).Error
	})
}

// DeleteWiki 删除百科
func (s *WikiService) DeleteWiki(req common.IdsReq) error {
	err := global.DB.Transaction(func(tx *gorm.DB) error {
		var imgIds []string
		tx.Table("sundynix_wiki_oss").Where("wiki_id IN ?", req.Ids).Pluck("oss_id", &imgIds)
		// 3. 物理删除图片记录本身
		if len(imgIds) > 0 {
			if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
				return err
			}
		}
		// 2. 清理中间表记录 (解开多对多关系)
		// 使用 Exec 直接操作中间表比循环 Clear 快得多
		if err := tx.Exec("DELETE FROM sundynix_wiki_oss WHERE wiki_id IN ?", req.Ids).Error; err != nil {
			return err
		}
		if err := tx.Exec("DELETE FROM sundynix_wiki_class WHERE wiki_id IN ?", req.Ids).Error; err != nil {
			return err
		}
		if err := tx.Exec("DELETE FROM sundynix_wiki_related WHERE wiki_id IN ? or related_wiki_id in ?", req.Ids, req.Ids).Error; err != nil {
			return err
		}
		//删除百科本身
		return tx.Unscoped().Where("id IN ?", req.Ids).Delete(&plant.Wiki{}).Error
	})
	if err == nil {
		// 异步清理 Qdrant 向量点位
		aiRagService.DeleteFromQdrantBatch(req.Ids)
	}
	return err
}
