package backend

import (
	"context"
	"fmt"
	"kpt-pasture/model"
	"kpt-pasture/util"
	"net/http"
	"strings"
	"time"

	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
	"gitee.com/xuyiping_admin/pkg/xerr"
	"gorm.io/gorm"
)

func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchLavingEventResponse, error) {
	lavingList := make([]*model.EventCalvingList, 0)
	var count int64 = 0
	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCalving).TableName())).
		Select(`a.*,b.name as pen_name,c.name as staff_member_name`).
		Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())).
		Joins(fmt.Sprintf("JOIN %s AS c on a.staff_member_id = c.id", new(model.SystemUser).TableName()))
	if len(req.CowId) > 0 {
		cowIds := strings.Split(req.CowId, ",")
		pref.Where("a.cow_id IN ?", cowIds)
	}

	if err := pref.Order("a.id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&lavingList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	calvingIds := make([]int64, 0)
	for _, v := range lavingList {
		calvingIds = append(calvingIds, v.Id)
	}
	calvingCalfList := make([]*model.CalvingCalf, 0)
	if err := s.DB.Model(new(model.CalvingCalf)).
		Where("calving_id IN ?", calvingIds).
		Find(&calvingCalfList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	return &pasturePb.SearchLavingEventResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.SearchLavingData{
			List:     model.EventCalvingListSlice(lavingList).ToPB(calvingCalfList),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}

func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) error {
	if len(req.CowId) <= 0 {
		return xerr.Custom("请选择相关牛只")
	}

	cowList, err := s.ParseCowIds(ctx, req.CowId)
	if err != nil {
		return xerr.WithStack(err)
	}

	if len(cowList) <= 0 {
		return xerr.Custom("请选择相关牛只")
	}

	cow := cowList[0]
	newEventCalving := &model.EventCalving{}
	if err = s.DB.Model(new(model.EventCalving)).Where("cow_id = ?", cow.Id).Where("lact = ?", cow.Lact).First(newEventCalving).Error; err != nil {
		return xerr.Custom("该母牛信息不存在")
	}

	if err = s.DB.Transaction(func(tx *gorm.DB) error {
		// 母牛信息
		if err = tx.Model(new(model.EventCalving)).
			Where("id = ?", newEventCalving.Id).
			Updates(map[string]interface{}{
				"reality_day":   time.Unix(int64(req.CalvingAt), 0).Format(model.LayoutTime),
				"day_age":       cow.DayAge,
				"lact":          cow.Lact + 1,
				"pregnancy_age": cow.PregnancyAge,
				"calving_level": req.CalvingLevel,
				"bull_number":   cow.LastBullNumber,
				"child_number":  len(req.CalfItemList),
			}).
			Error; err != nil {
			return xerr.WithStack(err)
		}
		// 犊牛信息
		newCalvingCalfList := model.NewEventCalvingCalf(cow.Id, newEventCalving.Id, req)
		for _, v := range newCalvingCalfList {
			if v.IsLive == pasturePb.IsShow_No || v.IsAdoption == pasturePb.IsShow_No {
				continue
			}
			// 留养犊牛
			newCow := model.NewCalfCow(cow.Id, cow.LastBullNumber, v)
			if err = tx.Create(newCow).Error; err != nil {
				return xerr.WithStack(err)
			}
			v.CowId = newCow.Id
		}
		if err = tx.Create(newCalvingCalfList).Error; err != nil {
			return xerr.WithStack(err)
		}

		if err = tx.Model(new(model.Cow)).Where("id = ?", cow.Id).Updates(map[string]interface{}{
			"calving_age":     0,
			"lact":            cow.Lact + 1,
			"breed_status":    pasturePb.BreedStatus_Calving,
			"is_pregnant":     pasturePb.IsShow_No,
			"calving_at":      0,
			"last_calving_at": time.Now().Unix(),
		}).Error; err != nil {
			return xerr.WithStack(err)
		}

		return nil
	}); err != nil {
		return xerr.WithStack(err)
	}
	return nil
}

func (s *StoreEntry) PregnantCheckList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnantCheckEventResponse, error) {
	pregnantCheckList := make([]*model.EventPregnantCheck, 0)
	var count int64 = 0
	pref := s.DB.Table(new(model.EventPregnantCheck).TableName())
	if len(req.CowId) > 0 {
		cowIds := strings.Split(req.CowId, ",")
		pref.Where("cow_id IN ?", cowIds)
	}

	if err := pref.Order("id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&pregnantCheckList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	pregnantCheckResultMap := s.PregnantCheckResultMap()
	pregnantCheckMethodMap := s.PregnantCheckMethodMap()
	return &pasturePb.PregnantCheckEventResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.SearchPregnantCheckData{
			List:     model.EventPregnantCheckSlice(pregnantCheckList).ToPB(pregnantCheckResultMap, pregnantCheckMethodMap),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}

func (s *StoreEntry) PregnantCheckCreate(ctx context.Context, req *pasturePb.EventPregnantCheck) error {
	if len(req.CowId) <= 0 {
		return xerr.Custom("请选择相关牛只")
	}
	cowList, err := s.ParseCowIds(ctx, req.CowId)
	if err != nil {
		return xerr.WithStack(err)
	}
	systemUser, _ := s.GetSystemUserById(ctx, int64(req.StaffMemberId))

	pregnantCheckDay := time.Unix(int64(req.PregnantCheckAt), 0).Format(model.LayoutTime)
	// 更新怀孕牛只
	updatePregnantCowIds := make([]int64, 0)
	// 更新流产牛只
	updateAbortCowIds := make([]int64, 0)
	// 更新空怀牛只
	updateEmptyCowIds := make([]int64, 0)
	cowIds := make([]int64, 0)
	for _, cow := range cowList {
		// 过滤掉没有配种状态的牛只
		if cow.BreedStatus != pasturePb.BreedStatus_Breeding {
			continue
		}

		itemEventPregnantCheck := &model.EventPregnantCheck{}
		if err = s.DB.Model(new(model.EventPregnantCheck)).
			Where("lact = ?", cow.Lact).
			Where("cow_id = ?", cow.Id).
			Order("id desc").First(itemEventPregnantCheck).Error; err != nil {
			return xerr.WithStack(err)
		}

		if req.PregnantCheckResult == pasturePb.PregnantCheckResult_Pregnant {
			updatePregnantCowIds = append(updatePregnantCowIds, cow.Id)
		}

		if req.PregnantCheckResult == pasturePb.PregnantCheckResult_UnPregnant {
			if itemEventPregnantCheck.PregnantCheckName == model.PregnantCheckForFirst {
				updateAbortCowIds = append(updateAbortCowIds, cow.Id)
			}
			if itemEventPregnantCheck.PregnantCheckName == model.PregnantCheckForSecond {
				updateEmptyCowIds = append(updateEmptyCowIds, cow.Id)
			}
		}
		cowIds = append(cowIds, cow.Id)
	}

	if err = s.DB.Transaction(func(tx *gorm.DB) error {
		// 更新孕检事件表
		if err = tx.Model(new(model.EventPregnantCheck)).
			Where("id IN ?", cowIds).
			Updates(map[string]interface{}{
				"reality_day":           pregnantCheckDay,
				"pregnant_check_result": req.PregnantCheckResult,
				"pregnant_check_method": req.PregnantCheckMethod,
				"operation_id":          systemUser.Id,
				"operation_name":        systemUser.Name,
				"remarks":               req.Remarks,
				"is_pregnant":           req.PregnantCheckResult,
			}).Error; err != nil {
			return xerr.WithStack(err)
		}
		// 更新牛只信息和配种事件表怀孕状态
		if len(updatePregnantCowIds) > 0 {
			if err = tx.Model(&model.Cow{}).Where("cow_id IN ?", updatePregnantCowIds).
				Updates(map[string]interface{}{
					"breed_status":           pasturePb.BreedStatus_Pregnant,
					"last_pregnant_check_at": pregnantCheckDay,
					"is_pregnant":            pasturePb.IsShow_Ok,
				}).Error; err != nil {
				return xerr.WithStack(err)
			}

			if err = tx.Model(&model.EventMating{}).Where("cow_id IN ?", updatePregnantCowIds).
				Group("cow_id").Select("MAX(id) as id").
				Updates(map[string]interface{}{"mating_result": pasturePb.MatingResult_Pregnant}).Error; err != nil {
				return xerr.WithStack(err)
			}
		}
		// 更新牛只信息和配种事件表流产状态
		if len(updateAbortCowIds) > 0 {
			if err = tx.Model(&model.Cow{}).Where("cow_id IN ?", updateAbortCowIds).
				Updates(map[string]interface{}{
					"breed_status":           pasturePb.BreedStatus_Abort,
					"last_pregnant_check_at": pregnantCheckDay,
					"is_pregnant":            pasturePb.IsShow_Ok,
				}).Error; err != nil {
				return xerr.WithStack(err)
			}

			if err = tx.Model(&model.EventMating{}).Where("cow_id IN ?", updateAbortCowIds).
				Group("cow_id").Select("MAX(id) as id").
				Updates(map[string]interface{}{"mating_result": pasturePb.MatingResult_Abort}).Error; err != nil {
				return xerr.WithStack(err)
			}
		}
		// 更新牛只信息和配种事件表空怀状态
		if len(updateEmptyCowIds) > 0 {
			if err = tx.Model(&model.Cow{}).Where("cow_id IN ?", updateEmptyCowIds).
				Updates(map[string]interface{}{
					"breed_status":           pasturePb.BreedStatus_Empty,
					"last_pregnant_check_at": pregnantCheckDay,
					"is_pregnant":            pasturePb.IsShow_Ok,
				}).Error; err != nil {
				return xerr.WithStack(err)
			}

			if err = tx.Model(&model.EventMating{}).Where("cow_id IN ?", updateEmptyCowIds).
				Group("cow_id").Select("MAX(id) as id").
				Updates(map[string]interface{}{"mating_result": pasturePb.MatingResult_Empty}).Error; err != nil {
				return xerr.WithStack(err)
			}
		}
		return nil
	}); err != nil {
		return xerr.WithStack(err)
	}

	return nil
}

func (s *StoreEntry) MatingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingEventResponse, error) {
	matingList := make([]*model.EventMating, 0)
	var count int64 = 0
	pref := s.DB.Model(new(model.EventMating)).
		Where("mating_result > ?", pasturePb.MatingResult_Invalid).
		Where("status = ?", pasturePb.IsShow_No)
	if len(req.CowId) > 0 {
		cowIds := strings.Split(req.CowId, ",")
		pref.Where("cow_id IN ?", cowIds)
	}

	if err := pref.Order("id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&matingList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	exposeEstrusTypeMap := s.ExposeEstrusTypeMap()
	return &pasturePb.MatingEventResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.SearchMatingData{
			List:     model.EventMatingSlice(matingList).ToPB(exposeEstrusTypeMap),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}

func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMating) error {
	if len(req.CowId) <= 0 {
		return xerr.Custom("请选择相关牛只")
	}
	cowList, err := s.ParseCowIds(ctx, req.CowId)
	if err != nil {
		return xerr.WithStack(err)
	}

	systemUser, _ := s.GetSystemUserById(ctx, int64(req.StaffMemberId))
	eventFrozenSemenLogList := make([]*model.FrozenSemenLog, 0)
	frozenSemen := &model.FrozenSemen{}
	if err = s.DB.Where("bull_id = ?", req.FrozenSemenNumber).First(frozenSemen).Error; err != nil {
		return xerr.WithStack(err)
	}

	matingUpdateIds := make([]int64, 0)
	cowIds := make([]int64, 0)
	nowTime := time.Now()
	for _, cow := range cowList {
		var count int64 = 0
		itemEventMating := &model.EventMating{}
		if err = s.DB.Where("lact = ?", cow.Lact).
			Where("cow_id = ?", cow.Id).
			Order("id desc").
			First(itemEventMating).Count(&count).Error; err != nil {
			return xerr.WithStack(err)
		}

		// 判断当前输精时间距离上次输精时间是否超过2天,如果超过则更新为复配状态
		itemBeforeTwoDays := nowTime.Sub(time.Unix(util.TimeParseLocalUnix(itemEventMating.RealityDay), 0)).Hours()
		if count > 0 && itemBeforeTwoDays > 48 {
			matingUpdateIds = append(matingUpdateIds, itemEventMating.Id)
		}

		eventFrozenSemenLogList = append(
			eventFrozenSemenLogList,
			model.NewEventFrozenSemenLog(req.FrozenSemenNumber, cow, int64(req.StaffMemberId)),
		)

		cowIds = append(cowIds, cow.Id)
	}

	if err = s.DB.Transaction(func(tx *gorm.DB) error {
		if len(cowIds) > 0 {
			// 如果有同期牛只,则修改为已结束状态
			if err = tx.Table(new(model.CowSameTime).TableName()).
				Where("cow_id IN ?", cowIds).
				UpdateColumn("status", pasturePb.SameTimeStatus_End).Error; err != nil {
			}

			// 创建配种事件数据
			if err = tx.Model(new(model.EventMating)).
				Where("cow_id IN ?", cowIds).
				Updates(map[string]interface{}{
					"mating_result":       pasturePb.MatingResult_Unknown,
					"status":              pasturePb.IsShow_Ok,
					"reality_day":         time.Unix(int64(req.MatingAt), 0).Format(model.LayoutTime),
					"mating_number":       1,
					"frozen_semen_number": req.FrozenSemenCount,
					"operation_id":        req.StaffMemberId,
					"operation_name":      systemUser.Name,
				}).
				Error; err != nil {
				return xerr.WithStack(err)
			}
		}

		// 更新已配种的牛只为复配状态
		if len(matingUpdateIds) > 0 {
			if err = tx.Model(new(model.EventMating)).
				Where("id IN ?", matingUpdateIds).
				Where("mating_result = ?", pasturePb.MatingResult_Unknown).
				Updates(map[string]interface{}{
					"mating_result":       pasturePb.MatingResult_ReMatch,
					"mating_number":       2,
					"frozen_semen_number": req.FrozenSemenCount,
				}).
				Error; err != nil {
				return xerr.WithStack(err)
			}
		}

		// 创建冻精使用记录日志
		if err = tx.Create(eventFrozenSemenLogList).Error; err != nil {
			return xerr.WithStack(err)
		}

		// 减去精液的数量
		if err = tx.Model(new(model.FrozenSemen)).
			Where("id = ?", frozenSemen.Id).
			Where("quantity > 0").
			UpdateColumn("quantity",
				gorm.Expr("quantity - ?", len(matingUpdateIds)),
			).Error; err != nil {
			return xerr.WithStack(err)
		}

		if err = tx.Table(new(model.Cow).TableName()).
			Where("id IN ?", cowIds).
			Updates(map[string]interface{}{
				"breed_status":     pasturePb.BreedStatus_Breeding,
				"last_bull_number": req.FrozenSemenNumber,
				"last_mating_at":   int64(req.MatingAt),
			}).Error; err != nil {
			return xerr.WithStack(err)
		}

		return nil
	}); err != nil {
		return xerr.WithStack(err)
	}

	return nil
}

func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusEventResponse, error) {
	estrusList := make([]*model.EventEstrus, 0)
	var count int64 = 0
	pref := s.DB.Table(new(model.EventEstrus).TableName())
	if len(req.CowId) > 0 {
		cowIds := strings.Split(req.CowId, ",")
		pref.Where("cow_id IN ?", cowIds)
	}

	if err := pref.Order("id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&estrusList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	systemUserList, _ := s.SystemUserList(ctx)
	return &pasturePb.EstrusEventResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.SearchEstrusData{
			List:     model.EstrusSlice(estrusList).ToPB(systemUserList),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}

func (s *StoreEntry) EstrusCreate(ctx context.Context, req *pasturePb.EventEstrus) error {
	if len(req.CowId) <= 0 {
		return xerr.Custom("请选择相关牛只")
	}
	cowList, err := s.ParseCowIds(ctx, req.CowId)
	if err != nil {
		return xerr.WithStack(err)
	}
	estrusList := make([]*model.EventEstrus, 0)
	currentUser, _ := s.GetCurrentSystemUser(ctx)

	for _, cow := range cowList {
		estrusList = append(estrusList, model.NewEventEstrus(cow, currentUser, req))
	}

	if err := s.DB.Create(estrusList).Error; err != nil {
		return xerr.WithStack(err)
	}
	return nil
}

func (s *StoreEntry) FrozenSemenList(ctx context.Context, req *pasturePb.FrozenSemenRequest, pagination *pasturePb.PaginationModel) (*pasturePb.FrozenSemenResponse, error) {
	frozenSemenList := make([]*model.FrozenSemen, 0)
	var count int64 = 0
	pref := s.DB.Table(new(model.FrozenSemen).TableName())
	if req.BullId != "" {
		pref.Where("bull_id = ?", req.BullId)
	}

	if req.Producer != "" {
		pref.Where("producer = ?", req.Producer)
	}

	if err := pref.Order("id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&frozenSemenList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	frozenSemenTypeMap := s.FrozenSemenTypeMap()
	unitMap := s.UnitMap()

	return &pasturePb.FrozenSemenResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.SearchFrozenSemenData{
			List:     model.FrozenSemenSlice(frozenSemenList).ToPB(frozenSemenTypeMap, unitMap),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}

func (s *StoreEntry) FrozenSemenCreate(ctx context.Context, req *pasturePb.SearchFrozenSemenList) error {
	currentUser, _ := s.GetCurrentSystemUser(ctx)
	req.CowKindName = s.CowKindMap()[req.CowKind]
	newFrozenSemen := model.NewFrozenSemen(req, currentUser)
	if err := s.DB.Create(newFrozenSemen).Error; err != nil {
		return xerr.WithStack(err)
	}
	return nil
}

func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSameTime) error {
	if _, err := s.GetSameTimeById(ctx, int64(req.SameTimeId)); err != nil {
		return xerr.WithStack(err)
	}

	cowList, err := s.ParseCowIds(ctx, req.CowId)
	if err != nil {
		return xerr.WithStack(err)
	}
	cowIds := make([]int64, 0)
	for _, v := range cowList {
		cowIds = append(cowIds, v.Id)
	}

	drugs := &model.Drugs{}
	if req.DrugsId > 0 {
		if drugs, err = s.GetDrugsById(ctx, int64(req.DrugsId)); err != nil {
			return xerr.WithStack(err)
		}
	}
	systemUser, _ := s.GetSystemUserById(ctx, int64(req.StaffMemberId))

	if err = s.DB.Transaction(func(tx *gorm.DB) error {
		if err = tx.Model(new(model.CowSameTime)).
			Where("cow_id IN ?", cowIds).
			Where("same_time_id = ?", req.SameTimeId).
			Update("same_time_status", pasturePb.SameTimeStatus_In_Progress).Error; err != nil {
			return xerr.WithStack(err)
		}

		if err = tx.Model(new(model.EventCowSameTime)).
			Where("cow_id IN ?", cowIds).
			Where("same_time_id = ?", req.SameTimeId).
			Where("same_time_type = ?", req.SameTimeType).
			Updates(map[string]interface{}{
				"status":         pasturePb.IsShow_Ok,
				"drug_id":        drugs.Id,
				"unit":           drugs.Unit,
				"usage":          req.Usage,
				"remarks":        req.Remarks,
				"operation_id":   req.StaffMemberId,
				"operation_name": systemUser.Name,
			}).Error; err != nil {
			return xerr.WithStack(err)
		}

		return nil
	}); err != nil {
		return xerr.WithStack(err)
	}
	return nil
}

func (s *StoreEntry) AbortionCreate(ctx context.Context, req *pasturePb.EventAbortionRequest) error {
	cow, err := s.GetCowInfoByCowId(ctx, int64(req.CowId))
	if err != nil {
		return xerr.WithStack(err)
	}

	systemUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
	if err != nil {
		return xerr.WithStack(err)
	}

	req.OperationName = systemUser.Name
	abortionReasonsMap := s.AbortionReasonsMap()
	newEventAbortion := model.NewEventAbortion(cow, req, abortionReasonsMap)

	lastCowMating := &model.EventMating{}
	if err = s.DB.Where("cow_id = ?", cow.Id).Order("id desc").First(lastCowMating).Error; err != nil {
		return xerr.WithStack(err)
	}
	if err = s.DB.Transaction(func(tx *gorm.DB) error {
		// 创建牛只流产事件数据
		if err = tx.Create(newEventAbortion).Error; err != nil {
			return xerr.WithStack(err)
		}
		// 更新牛只状态
		if err = tx.Model(new(model.Cow)).Where("id = ?", req.CowId).
			Updates(map[string]interface{}{
				"is_pregnant":      pasturePb.IsShow_No,
				"last_abortion_at": req.AbortionAt,
				"breed_status":     pasturePb.BreedStatus_Abort,
			}).Error; err != nil {
			return xerr.WithStack(err)
		}

		// 更新最近一次配种结果为流产
		if err = tx.Model(new(model.EventMating)).Where("id = ?", lastCowMating.Id).
			Updates(map[string]interface{}{
				"mating_result": pasturePb.MatingResult_Abort,
			}).Error; err != nil {
		}
		return nil
	}); err != nil {
		return xerr.WithStack(err)
	}

	return nil
}

func (s *StoreEntry) AbortionList(
	ctx context.Context,
	req *pasturePb.SearchEventRequest,
	pagination *pasturePb.PaginationModel,
) (*pasturePb.EventAbortionResponse, error) {
	abortionList := make([]*model.EventAbortion, 0)
	var count int64 = 0
	pref := s.DB.Model(new(model.EventAbortion))
	if len(req.CowId) > 0 {
		cowIds := strings.Split(req.CowId, ",")
		pref.Where("cow_id IN ?", cowIds)
	}

	if err := pref.Order("id desc").
		Count(&count).Limit(int(pagination.PageSize)).
		Offset(int(pagination.PageOffset)).
		Find(&abortionList).Error; err != nil {
		return nil, xerr.WithStack(err)
	}

	return &pasturePb.EventAbortionResponse{
		Code:    http.StatusOK,
		Message: "ok",
		Data: &pasturePb.EventAbortionData{
			List:     model.AbortionSlice(abortionList).ToPB(),
			Total:    int32(count),
			PageSize: pagination.PageSize,
			Page:     pagination.Page,
		},
	}, nil
}