package backend

import (
	"bytes"
	"context"
	"io"
	"kpt-tmr-group/config"
	"kpt-tmr-group/model"
	"kpt-tmr-group/pkg/di"
	operationPb "kpt-tmr-group/proto/go/backend/operation"
	"kpt-tmr-group/service/wechat"
	"kpt-tmr-group/store/kptstore"

	"go.uber.org/dig"
)

var Module = di.Options(di.Provide(NewStore))

type Hub struct {
	dig.In
	OpsService KptService
}

type StoreEntry struct {
	dig.In

	Cfg        *config.AppConfig
	DB         *kptstore.DB
	HttpClient *wechat.ClientService
}

func NewStore(store StoreEntry) KptService {
	return &store
}

func NewStoreEntry(cfg *config.AppConfig, Db *kptstore.DB) *StoreEntry {
	return &StoreEntry{
		Cfg:        cfg,
		DB:         Db,
		HttpClient: nil,
	}
}

//go:generate mockgen -destination mock/kptservice.go -package kptservicemock kpt-tmr-group/module/backend KptService
type KptService interface {
	PastureService     // 牧场相关操作
	SystemService      // 系统相关操作
	WxAppletService    // 小程序相关
	StatisticService   // 统计分析
	PastureSyncService // 牧场端数据同步
}

type PastureService interface {
	// CreateGroupPasture 牧场管理相关
	CreateGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
	EditGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
	SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*operationPb.SearchPastureResponse, error)
	DeleteGroupPasture(ctx context.Context, pastureId int64) error
	ResetPasswordGroupPasture(ctx context.Context, pastureId int64) error
	IsShowGroupPasture(ctx context.Context, req *operationPb.IsShowGroupPasture) error

	// AddCattleCategory 牧畜类别
	AddCattleCategory(ctx context.Context, req *operationPb.AddCattleCategoryRequest) error
	EditCattleCategory(ctx context.Context, req *operationPb.AddCattleCategoryRequest) error
	IsShowCattleCategory(ctx context.Context, req *operationPb.IsShowCattleCategory) error
	DeleteCattleCategory(ctx context.Context, cattleCategoryId int64) error
	SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*operationPb.SearchCattleCategoryResponse, error)

	// AddForageCategory 饲料类别相关
	AddForageCategory(ctx context.Context, req *operationPb.AddForageCategoryRequest) error
	EditForageCategory(ctx context.Context, req *operationPb.AddForageCategoryRequest) error
	IsShowForageCategory(ctx context.Context, req *operationPb.IsShowForageCategory) error
	DeleteForageCategory(ctx context.Context, cattleCategoryId int64) error
	SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*operationPb.SearchForageCategoryResponse, error)

	// CreateForage 饲料相关
	CreateForage(ctx context.Context, req *operationPb.AddForageRequest) error
	EditForage(ctx context.Context, req *operationPb.AddForageRequest) error
	SearchForageList(ctx context.Context, req *operationPb.SearchForageListRequest) (*operationPb.SearchForageListResponse, error)
	ForageListSort(ctx context.Context, req *operationPb.ForageListSortRequest) error
	ForageEnumList(ctx context.Context) *operationPb.ForageEnumListResponse
	DeleteForageList(ctx context.Context, ids []int64) error
	IsShowForage(ctx context.Context, req *operationPb.IsShowForage) error
	ExcelImportForage(ctx context.Context, req io.Reader) error
	ExcelExportForage(ctx context.Context, req *operationPb.SearchForageListRequest) (*bytes.Buffer, error)
	ExcelTemplateForage(ctx context.Context) (*bytes.Buffer, error)
	SmallMaterial(ctx context.Context, req *operationPb.SmallMaterialRequest) (*model.PastureCommonResponse, error)

	// CreateFeedFormula 饲料配方
	CreateFeedFormula(ctx context.Context, req *operationPb.AddFeedFormulaRequest) error
	EditFeedFormula(ctx context.Context, req *operationPb.AddFeedFormulaRequest) error
	SearchFeedFormulaList(ctx context.Context, req *operationPb.SearchFeedFormulaRequest) (*operationPb.SearchFeedFormulaListResponse, error)
	IsShowFeedFormula(ctx context.Context, req *operationPb.IsShowModifyFeedFormula) error
	DeleteFeedFormula(ctx context.Context, feedFormulaId int64) error
	ExcelImportFeedFormula(ctx context.Context, req io.Reader) error
	ExcelExportFeedFormula(ctx context.Context, req *operationPb.SearchFeedFormulaRequest) (*bytes.Buffer, error)
	ExcelTemplateFeedFormula(ctx context.Context) (*bytes.Buffer, error)
	EncodeNumber(ctx context.Context) string
	DistributeFeedFormula(ctx context.Context, req *operationPb.DistributeFeedFormulaRequest) error
	FeedFormulaUsage(ctx context.Context, req *operationPb.FeedFormulaUsageRequest) error
}

type SystemService interface {
	// Auth 系统用户相关
	Auth(ctx context.Context, auth *operationPb.UserAuthData) (*operationPb.SystemToken, error)
	GetUserInfo(ctx context.Context, token string) (*operationPb.UserAuth, error)
	CreateSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
	SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*operationPb.SearchUserResponse, error)
	EditSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
	DeleteSystemUser(ctx context.Context, userId int64) error
	ResetPasswordSystemUser(ctx context.Context, userId int64) error
	DetailsSystemUser(ctx context.Context, userId int64) (*operationPb.UserDetails, error)
	IsShowSystemUser(ctx context.Context, req *operationPb.IsShowSystemUserRequest) error
	GetSystemUserPermissions(ctx context.Context, token string) (*operationPb.SystemUserMenuPermissions, error)

	// CreateSystemRole 系统角色相关
	CreateSystemRole(ctx context.Context, req *operationPb.AddRoleRequest) error
	EditSystemRole(ctx context.Context, req *operationPb.AddRoleRequest) error
	DeleteSystemRole(ctx context.Context, roleId int64) error
	GetRolePermissions(ctx context.Context, roleId int64) (*operationPb.RolePermissionsList, error)
	SearchSystemRoleList(ctx context.Context, req *operationPb.SearchRoleRequest) (*operationPb.SearchRoleResponse, error)

	// CreateSystemMenu 系统菜单权限
	CreateSystemMenu(ctx context.Context, req *operationPb.AddMenuRequest) error
	EditSystemMenu(ctx context.Context, req *operationPb.AddMenuRequest) error
	IsShowSystemMenu(ctx context.Context, req *operationPb.IsShowSystemMenuRequest) error
	SearchSystemMenuList(ctx context.Context, req *operationPb.SearchMenuRequest) (*operationPb.SearchMenuResponse, error)
	DeleteSystemMenu(ctx context.Context, menuId int64) error

	// SearchMobileList 移动端
	SearchMobileList(ctx context.Context, req *operationPb.SearchMobileRequest) (*operationPb.SearchMobileResponse, error)
}

type StatisticService interface {
	SearchFormulaEstimateList(ctx context.Context, req *operationPb.SearchFormulaEstimateRequest) (*model.PastureCommonResponse, error)
	SearchInventoryStatistics(ctx context.Context, req *operationPb.SearchInventoryStatisticsRequest) (*model.PastureCommonResponse, error)
	InventoryStatisticsExcelExport(ctx context.Context, req *operationPb.SearchInventoryStatisticsRequest) (*bytes.Buffer, error)

	SearchUserMaterialsStatistics(ctx context.Context, req *operationPb.SearchUserMaterialsStatisticsRequest) (*model.PastureCommonResponse, error)
	UserMaterialsStatisticsExcelExport(ctx context.Context, req *operationPb.SearchUserMaterialsStatisticsRequest) (*bytes.Buffer, error)
	SearchPriceStatistics(ctx context.Context, req *operationPb.SearchPriceStatisticsRequest) (*model.PastureCommonResponse, error)
	SearchFeedStatistics(ctx context.Context, req *operationPb.SearchFeedStatisticsRequest) (*model.FeedStatisticsResponse, error)
	FeedChartStatistics(ctx context.Context, req *operationPb.FeedChartStatisticsRequest) (*model.PastureCommonResponse, error)
	CowsAnalysis(ctx context.Context, req *operationPb.CowsAnalysisRequest) (*model.PastureCommonResponse, error)

	SearchAccuracyAggStatistics(ctx context.Context, req *operationPb.AccuracyAggStatisticsRequest) (*model.PastureCommonResponse, error)
	SearchMixFeedStatistics(ctx context.Context, req *operationPb.MixFeedStatisticsRequest) (*model.PastureCommonResponse, error)
	SearchSprinkleStatistics(ctx context.Context, req *operationPb.SprinkleStatisticsRequest) (*model.PastureCommonResponse, error)
	SearchProcessAnalysis(ctx context.Context, req *operationPb.ProcessAnalysisRequest) (*model.PastureCommonResponse, error)
	AnalysisMixedSprinkleDetail(ctx context.Context, req *operationPb.ProcessMixedSprinkleDetailRequest) (*model.PastureCommonResponse, error)
	GetDataByName(ctx context.Context, req *operationPb.GetDataByNameRequest) (*model.PastureCommonResponse, error)

	GetTrainNumber(ctx context.Context, req *operationPb.TrainNumberRequest) (*operationPb.TrainNumberResponse, error)
	SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error)
	TopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.GetPastureTopResponse, error)
	ExecutionTime(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.ExecTimeResponse, error)
	SprinkleFeedTime(ctx context.Context, req *operationPb.SprinkleFeedTimeRequest) (*model.SprinkleFeedTimeResponse, error)
	FeedMixedAndTmrName(ctx context.Context, req *operationPb.MixedCategoryTmrName) (*model.PastureCommonResponse, error)
}

type WxAppletService interface {
	GetOpenId(ctx context.Context, jsCode string) (*operationPb.WxOpenId, error)
}

type PastureSyncService interface {
	CategorySyncData(ctx context.Context, req *operationPb.CategorySyncRequest) error
	CategoryDeleteData(ctx context.Context, req *operationPb.CategoryDeleteRequest) error
	FeedFormulaSyncData(ctx context.Context, req *operationPb.FeedFormulaSyncRequest) error
}