package event

import (
	"kpt-pasture/http/middleware"
	"net/http"

	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
	"gitee.com/xuyiping_admin/pkg/apierr"
	"gitee.com/xuyiping_admin/pkg/ginutil"
	"gitee.com/xuyiping_admin/pkg/valid"
	"github.com/gin-gonic/gin"
)

func CalvingEventList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.CalvingList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func CalvingEventCreate(c *gin.Context) {
	var req pasturePb.EventCalving
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.EarNumber, valid.Required),
		valid.Field(&req.CalvingAt, valid.Required),
		valid.Field(&req.ChildNumber, valid.Required),
		valid.Field(&req.CalvingLevel, valid.Required),
		valid.Field(&req.CalfItemList, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			s := value.(pasturePb.CalfItem)
			return valid.ValidateStruct(&s,
				valid.Field(&s.Sex, valid.Required),
				valid.Field(&s.Weight, valid.Required),
				valid.Field(&s.IsLive, valid.Required),
				valid.Field(&s.IsAdoption, valid.Required),
			)
		}))),
		valid.Field(&req.OperationId, valid.Required),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.CalvingCreate(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func PregnantCheckEventList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.PregnantCheckList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func PregnantCheckEventCreateBatch(c *gin.Context) {
	var req pasturePb.EventPregnantCheckBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			item := value.(pasturePb.EventPregnantCheckRequest)
			return valid.ValidateStruct(&item,
				valid.Field(&item.EarNumber, valid.Required),
				valid.Field(&item.PregnantCheckAt, valid.Required),
				valid.Field(&item.PregnantCheckResult, valid.Required),
				valid.Field(&item.PregnantCheckMethod, valid.Required),
				valid.Field(&item.OperationId, valid.Required),
			)
		}))),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.PregnantCheckCreateBatch(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func MatingEventList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.MatingList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func MatingBatch(c *gin.Context) {
	var req pasturePb.EventMatingBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			item := value.(pasturePb.EventMating)
			return valid.ValidateStruct(&item,
				valid.Field(&item.EarNumber, valid.Required),
				valid.Field(&item.OperationId, valid.Required),
				valid.Field(&item.FrozenSemenNumber, valid.Required),
				valid.Field(&item.MatingAt, valid.Required),
				valid.Field(&item.FrozenSemenCount, valid.Required, valid.Min(1)),
			)
		}))),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.MatingBatch(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func EstrusEventList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.EstrusList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func EstrusBatchMating(c *gin.Context) {
	var req pasturePb.EventNaturalEstrusBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			item := value.(pasturePb.EventNaturalEstrusItems)
			return valid.ValidateStruct(&item,
				valid.Field(&item.EarNumber, valid.Required),
				valid.Field(&item.EstrusAt, valid.Required),
				valid.Field(&item.IsMating, valid.Required),
				valid.Field(&item.OperationId, valid.Required),
			)
		}))),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.EstrusBatchMating(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}
func SameTimeCreate(c *gin.Context) {
	var req pasturePb.EventSameTime
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.Id, valid.Required),
		valid.Field(&req.DrugsId, valid.Required),
		valid.Field(&req.OperationId, valid.Required),
		valid.Field(&req.SameTimeAt, valid.Required),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.SameTimeCreate(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func SameTimeBatch(c *gin.Context) {
	var req pasturePb.EventSameTimeBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.OperationId, valid.Required),
		valid.Field(&req.DrugsId, valid.Required),
		valid.Field(&req.SameTimeAt, valid.Required),
		valid.Field(&req.CowIds, valid.Required),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.SameTimeBatch(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func SameTimeList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.SameTimeList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func AbortionCreateBatch(c *gin.Context) {
	var req pasturePb.EventAbortionBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			item := value.(pasturePb.EventAbortionItem)
			return valid.ValidateStruct(&item,
				valid.Field(&item.EarNumber, valid.Required),
				valid.Field(&item.IsAfterbirth, valid.Required),
				valid.Field(&item.AbortionReasons, valid.Required),
				valid.Field(&item.AbortionAt, valid.Required),
				valid.Field(&item.OperationId, valid.Required),
			)
		}))),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.AbortionCreateBatch(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}

	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}

func AbortionList(c *gin.Context) {
	var req pasturePb.SearchEventRequest
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	pagination := &pasturePb.PaginationModel{
		Page:       int32(c.GetInt(middleware.Page)),
		PageSize:   int32(c.GetInt(middleware.PageSize)),
		PageOffset: int32(c.GetInt(middleware.PageOffset)),
	}

	res, err := middleware.Dependency(c).StoreEventHub.OpsService.AbortionList(c, &req, pagination)
	if err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, res)
}

func WeaningCreateBatch(c *gin.Context) {
	var req pasturePb.EventWeaningBatch
	if err := ginutil.BindProto(c, &req); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := valid.ValidateStruct(&req,
		valid.Field(&req.WeaningAt, valid.Required),
		valid.Field(&req.OperationId, valid.Required),
		valid.Field(&req.PenId, valid.Required),
		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
			item := value.(pasturePb.WeaningItem)
			return valid.ValidateStruct(&item,
				valid.Field(&item.EarNumber, valid.Required),
				valid.Field(&item.Weight, valid.Required),
			)
		}))),
	); err != nil {
		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
		return
	}

	if err := middleware.BackendOperation(c).OpsService.WeaningBatch(c, &req); err != nil {
		apierr.ClassifiedAbort(c, err)
		return
	}
	ginutil.JSONResp(c, &operationPb.CommonOK{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: &operationPb.Success{Success: true},
	})
}