package dao

import (
	"micro-bundle/internal/model"
	"micro-bundle/pb/bundle"
	"micro-bundle/pkg/app"
	commonErr "micro-bundle/pkg/err"
	"micro-bundle/pkg/msg"
	"time"

	"gorm.io/gorm"
)

func CreateBundle(req *model.BundleProfile) (res *bundle.CommonResponse, err error) {
	res = new(bundle.CommonResponse)
	err = app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).Create(&req).Error
	if err != nil {
		res.Msg = msg.ErrorCreateBundleInfo
		return res, commonErr.ReturnError(err, msg.ErrorCreateBundleInfo, "创建套餐信息失败: ")
	}
	res.Msg = msg.SuccessCreateBundleInfo
	return
}

func UpdateBundle(req *model.BundleProfile) (res *bundle.CommonResponse, err error) {
	res = new(bundle.CommonResponse)
	err = app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).Where("uuid = ? and language= ?", req.UUID, req.Language).Updates(req).Error
	if err != nil {
		res.Msg = msg.ErrorUpdateBundleInfo
		return res, commonErr.ReturnError(err, msg.ErrorUpdateBundleInfo, "更新套餐信息失败: ")
	}
	res.Msg = msg.SuccessUpdateBundleInfo
	return
}

func DeleteBundle(uuid string) (res *bundle.CommonResponse, err error) {
	res = new(bundle.CommonResponse)
	err = app.ModuleClients.BundleDB.Where("uuid = ?", uuid).Delete(&model.BundleProfile{}).Error
	if err != nil {
		res.Msg = msg.ErrorDeleteBundleInfo
		return res, commonErr.ReturnError(err, msg.ErrorDeleteBundleInfo, "删除套餐信息失败: ")
	}
	res.Msg = msg.SuccessDeleteBundleInfo
	return
}

func BundleList(req *bundle.BundleListRequest) (res *bundle.BundleListResponse, err error) {
	res = new(bundle.BundleListResponse)
	res.Bundles = make([]*bundle.BundleProfile, 0)
	bundles := make([]*model.BundleProfile, 0)

	query := app.ModuleClients.BundleDB.Model(&model.BundleProfile{})

	if req.Name != "" {
		query = query.Where("name like ?", "%"+req.Name+"%")
	}

	if req.Content != "" {
		query = query.Where("content like ?", "%"+req.Content+"%")
	}

	if req.Language != "" {
		query = query.Where("language like ?", req.Language)
	}

	count := *query

	if req.PageSize != 0 && req.Page != 0 {
		query = query.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
	}

	if err = query.Find(&bundles).Error; err != nil {
		return res, commonErr.ReturnError(err, msg.ErrorGetBundleList, "获取套餐列表失败: ")
	}

	for _, bundleProfile := range bundles {
		res.Bundles = append(res.Bundles, &bundle.BundleProfile{
			Uuid:             bundleProfile.UUID,
			Name:             bundleProfile.Name,
			Price:            bundleProfile.Price,
			PriceType:        bundleProfile.PriceType,
			Contract:         bundleProfile.Contract,
			Content:          bundleProfile.Content,
			Language:         bundleProfile.Language,
			CreatedAt:        bundleProfile.CreatedAt.String(),
			UpdatedAt:        bundleProfile.UpdatedAt.String(),
			CompanySign:      bundleProfile.CompanySign,
			ContractDuration: int64(bundleProfile.ContractDuration),
			BundleCommonUid:  bundleProfile.BundleCommonUid,
		})
	}

	// _ = copier.CopyWithOption(&res.Bundles, bundles, copier.Option{DeepCopy: true})

	// fmt.Printf("res.Bundles %+v\n", res.Bundles)

	var total int64

	count.Count(&total)

	res.Total = int32(total)

	return

}

func BundleDetail(uuid string) (res *bundle.BundleProfile, err error) {
	res = new(bundle.BundleProfile)
	bundleProfile := new(model.BundleProfile)
	err = app.ModuleClients.BundleDB.Where("uuid = ?", uuid).First(&bundleProfile).Error
	if err != nil {
		return res, commonErr.ReturnError(err, msg.ErrorGetBundleInfo, "获取套餐信息失败: ")
	}
	//_ = copier.CopyWithOption(&res, bundle, copier.Option{DeepCopy: true})

	res = &bundle.BundleProfile{
		Uuid:             bundleProfile.UUID,
		Name:             bundleProfile.Name,
		Price:            bundleProfile.Price,
		PriceType:        bundleProfile.PriceType,
		Contract:         bundleProfile.Contract,
		Content:          bundleProfile.Content,
		Language:         bundleProfile.Language,
		CreatedAt:        bundleProfile.CreatedAt.String(),
		UpdatedAt:        bundleProfile.UpdatedAt.String(),
		CompanySign:      bundleProfile.CompanySign,
		ContractDuration: int64(bundleProfile.ContractDuration),
		BundleCommonUid:  bundleProfile.BundleCommonUid,
	}
	return
}

func BundleListV2(req *bundle.BundleListRequest) (res *bundle.BundleListResponse, err error) {
	res = new(bundle.BundleListResponse)
	res.Bundles = make([]*bundle.BundleProfile, 0)
	bundles := make([]*model.BundleProfile, 0)

	query := app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).Preload("BundleProfileLang")
	//query = query.Where("shelf_status = ?", 1) //上架的

	if req.Name != "" {
		query = query.Where("name like ?", "%"+req.Name+"%")
	}

	if req.Content != "" {
		query = query.Where("content like ?", "%"+req.Content+"%")
	}

	if req.Language != "" {
		query = query.Where("language like ?", req.Language)
	}

	count := *query

	// 排序:sort 升序,相同 sort 按 created_at 倒序
	query = query.Order("sort ASC").Order("created_at DESC")
	if req.PageSize != 0 && req.Page != 0 {
		query = query.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
	}

	if err = query.Preload("BundleToValueAddService").Find(&bundles).Error; err != nil {
		return res, commonErr.ReturnError(err, msg.ErrorGetBundleList, "获取套餐列表失败: ")
	}
	if bundles != nil && len(bundles) > 0 {
		for _, bundleProfile := range bundles {
			selectValueAddService := make([]*bundle.SelectValueAddService, 0)
			if bundleProfile.BundleToValueAddService != nil {
				for _, v := range bundleProfile.BundleToValueAddService {
					selectValueAddService = append(selectValueAddService, &bundle.SelectValueAddService{
						ValueAddUuid: v.ValueUid,
						IsDisplay:    v.IsDisplay,
					})
				}
			}
			bundleProfileLang := []*bundle.BundleProfileLang{}
			if bundleProfile.BundleProfileLang != nil && len(bundleProfile.BundleProfileLang) > 0 {
				for _, lang := range bundleProfile.BundleProfileLang {
					bpl := &bundle.BundleProfileLang{
						Uuid:      lang.UUID,
						Name:      lang.Name,
						Price:     lang.Price,
						PriceType: lang.PriceType,
						Content:   lang.Content,
						Language:  lang.Language,
						CreatedAt: time.Unix(lang.CreatedAt, 0).Format("2006-01-02 15:04:05"),
						UpdatedAt: time.Unix(int64(lang.UpdatedAt), 0).Format("2006-01-02 15:04:05"),
					}
					bundleProfileLang = append(bundleProfileLang, bpl)
				}
			}
			res.Bundles = append(res.Bundles, &bundle.BundleProfile{
				Uuid:                  bundleProfile.UUID,
				Name:                  bundleProfile.Name,
				Content:               bundleProfile.Content,
				Price:                 bundleProfile.Price,
				PriceType:             bundleProfile.PriceType,
				Contract:              bundleProfile.Contract,
				Language:              bundleProfile.Language,
				CreatedAt:             bundleProfile.CreatedAt.Format("2006-01-02 15:04:05"),
				UpdatedAt:             bundleProfile.UpdatedAt.Format("2006-01-02 15:04:05"),
				CompanySign:           bundleProfile.CompanySign,
				ContractDuration:      int64(bundleProfile.ContractDuration),
				Sort:                  bundleProfile.Sort,
				ImgOption:             int32(bundleProfile.ImgOption),
				BgImg1:                bundleProfile.BgImg1,
				BgImg2:                bundleProfile.BgImg2,
				SelectValueAddService: selectValueAddService,
				BundleProfileLang:     bundleProfileLang,
				ShelfStatus:           int64(bundleProfile.ShelfStatus),
			})
		}
	}

	var total int64

	count.Count(&total)

	res.Total = int32(total)

	return

}

func BundleDetailV2(req *bundle.BundleDetailRequest) (res *model.BundleProfile, err error) {
	var data model.BundleProfile
	err = app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).Where("uuid = ?", req.Uuid).
		Preload("BundleProfileLang").
		Preload("BundleToValueAddService").
		First(&data).Error
	if err != nil {
		return res, commonErr.ReturnError(err, msg.ErrorGetBundleInfo, "获取套餐信息失败: ")
	}
	return &data, nil
}

// 套餐上下架
func HandShelf(uuid string, shelfStatus int64) (res *bundle.CommonResponse, err error) {
	res = new(bundle.CommonResponse)
	err = app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).Where("uuid = ?", uuid).Update("shelf_status", shelfStatus).Error
	if err != nil {
		res.Msg = "套餐上下架操作失败"
		return res, err
	}
	res.Msg = "套餐上下架操作成功"
	return res, nil
}

// 通过uuid和language查询套餐语言表
func BundleDetailByUuidAndLanguage(uuid string, language string) (bundleProfileLang *model.BundleProfileLang, err error) {
	err = app.ModuleClients.BundleDB.Where("uuid = ? AND language = ?", uuid, language).First(&bundleProfileLang).Error
	if err != nil {
		return nil, err
	}
	return
}

// 套餐主表创建
func TxCreateBundle(tx *gorm.DB, req *model.BundleProfile) (err error) {
	err = tx.Model(&model.BundleProfile{}).Create(&req).Error
	if err != nil {
		return commonErr.ReturnError(err, msg.ErrorCreateBundleInfo, "创建套餐信息失败: ")
	}
	return
}

// 套餐语言表创建
func TxCreateBundleLang(tx *gorm.DB, req *model.BundleProfileLang) (err error) {
	err = tx.Model(&model.BundleProfileLang{}).Create(&req).Error
	if err != nil {
		return commonErr.ReturnError(err, msg.ErrorCreateBundleInfo, "创建套餐信息失败: ")
	}
	return
}
func TxUpdateBundle(tx *gorm.DB, uuid string, columns map[string]interface{}) (err error) {
	err = tx.Model(&model.BundleProfile{}).Where("uuid =?", uuid).Updates(columns).Error
	if err != nil {
		return commonErr.ReturnError(err, msg.ErrorUpdateBundleInfo, "更新套餐信息失败: ")
	}
	return
}
func TxUpdateBundleLang(tx *gorm.DB, uuid string, language string, columns map[string]interface{}) (err error) {
	err = tx.Model(&model.BundleProfileLang{}).Where("uuid =? and language=?", uuid, language).Updates(columns).Error
	if err != nil {
		return commonErr.ReturnError(err, msg.ErrorUpdateBundleInfo, "更新套餐信息失败: ")
	}
	return
}
func CreateBundleToValueAddService(tx *gorm.DB, records []*model.BundleToValueAddService) error {
	return tx.Model(&model.BundleToValueAddService{}).Create(&records).Error
}

func DeleteBundleToValueAddService(tx *gorm.DB, bundleUuid, valueUid string) error {
	return tx.Where("bundle_uuid = ? AND value_uid = ?", bundleUuid, valueUid).Delete(&model.BundleToValueAddService{}).Error
}
func GetValueAddServiceUuidsByBundleUuid(bundleUuid string) ([]string, error) {
	var uuids []string
	err := app.ModuleClients.BundleDB.Model(&model.BundleToValueAddService{}).Where("bundle_uuid = ?", bundleUuid).Pluck("value_uid", &uuids).Error
	return uuids, err
}

// GetBundleToValueAddServiceByBundleUuid 根据套餐UUID获取所有关联的增值服务uuid
func GetBundleToValueAddServiceByBundleUuid(bundleUuid string) ([]*model.BundleToValueAddService, error) {
	var result []*model.BundleToValueAddService
	err := app.ModuleClients.BundleDB.Model(&model.BundleToValueAddService{}).
		Where("bundle_uuid = ?", bundleUuid).
		Find(&result).Error
	return result, err
}

func GetBundleLangsByUuid(uuid string) ([]*model.BundleProfileLang, error) {
	var result []*model.BundleProfileLang
	err := app.ModuleClients.BundleDB.Model(&model.BundleProfileLang{}).
		Where("uuid =?", uuid).
		Find(&result).Error
	return result, err
}
func GetBundleDetailByUuid(uuid string) (*model.BundleProfile, error) {
	result := &model.BundleProfile{}
	err := app.ModuleClients.BundleDB.Model(&model.BundleProfile{}).
		Preload("BundleToValueAddService", "deleted_at = 0").
		Preload("BundleProfileLang", "deleted_at = 0").
		Where("uuid =?", uuid).
		First(&result).Error
	return result, err
}
func CreateBunldeHistory(tx *gorm.DB, req *model.BundleProfileHistory) error {
	return tx.Model(&model.BundleProfileHistory{}).Create(req).Error
}