package gameclient

import (
	"context"

	gamev1 "hyapp.local/api/proto/game/v1"

	"google.golang.org/grpc"
)

// Client 是 admin-server 管理游戏平台和目录配置的最小 gRPC 依赖。
type Client interface {
	ListPlatforms(ctx context.Context, req *gamev1.ListPlatformsRequest) (*gamev1.ListPlatformsResponse, error)
	UpsertPlatform(ctx context.Context, req *gamev1.UpsertPlatformRequest) (*gamev1.PlatformResponse, error)
	ListCatalog(ctx context.Context, req *gamev1.ListCatalogRequest) (*gamev1.ListCatalogResponse, error)
	UpsertCatalog(ctx context.Context, req *gamev1.UpsertCatalogRequest) (*gamev1.CatalogResponse, error)
	SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error)
	DeleteCatalog(ctx context.Context, req *gamev1.DeleteCatalogRequest) (*gamev1.DeleteCatalogResponse, error)
	SetGameWhitelistEnabled(ctx context.Context, req *gamev1.SetGameWhitelistEnabledRequest) (*gamev1.CatalogResponse, error)
	ListGameWhitelistUsers(ctx context.Context, req *gamev1.ListGameWhitelistUsersRequest) (*gamev1.ListGameWhitelistUsersResponse, error)
	AddGameWhitelistUser(ctx context.Context, req *gamev1.AddGameWhitelistUserRequest) (*gamev1.GameWhitelistUserResponse, error)
	DeleteGameWhitelistUser(ctx context.Context, req *gamev1.DeleteGameWhitelistUserRequest) (*gamev1.DeleteGameWhitelistUserResponse, error)
	ListSelfGames(ctx context.Context, req *gamev1.ListSelfGamesRequest) (*gamev1.ListSelfGamesResponse, error)
	UpdateDiceConfig(ctx context.Context, req *gamev1.UpdateDiceConfigRequest) (*gamev1.DiceConfigResponse, error)
	GetSelfGameNewUserPolicy(ctx context.Context, req *gamev1.GetSelfGameNewUserPolicyRequest) (*gamev1.SelfGameNewUserPolicyResponse, error)
	UpdateSelfGameNewUserPolicy(ctx context.Context, req *gamev1.UpdateSelfGameNewUserPolicyRequest) (*gamev1.SelfGameNewUserPolicyResponse, error)
	ListSelfGameStakePools(ctx context.Context, req *gamev1.ListSelfGameStakePoolsRequest) (*gamev1.ListSelfGameStakePoolsResponse, error)
	UpdateSelfGameStakePool(ctx context.Context, req *gamev1.UpdateSelfGameStakePoolRequest) (*gamev1.SelfGameStakePoolResponse, error)
	AdjustSelfGameStakePool(ctx context.Context, req *gamev1.AdjustSelfGameStakePoolRequest) (*gamev1.AdjustSelfGameStakePoolResponse, error)
	ListDiceRobots(ctx context.Context, req *gamev1.ListDiceRobotsRequest) (*gamev1.ListDiceRobotsResponse, error)
	RegisterDiceRobots(ctx context.Context, req *gamev1.RegisterDiceRobotsRequest) (*gamev1.RegisterDiceRobotsResponse, error)
	SetDiceRobotStatus(ctx context.Context, req *gamev1.SetDiceRobotStatusRequest) (*gamev1.DiceRobotResponse, error)
	DeleteDiceRobot(ctx context.Context, req *gamev1.DeleteDiceRobotRequest) (*gamev1.DeleteDiceRobotResponse, error)
	GetRoomRPSConfig(ctx context.Context, req *gamev1.GetRoomRPSConfigRequest) (*gamev1.RoomRPSConfigResponse, error)
	UpdateRoomRPSConfig(ctx context.Context, req *gamev1.UpdateRoomRPSConfigRequest) (*gamev1.RoomRPSConfigResponse, error)
	ListRoomRPSChallenges(ctx context.Context, req *gamev1.ListRoomRPSChallengesRequest) (*gamev1.ListRoomRPSChallengesResponse, error)
	GetRoomRPSChallenge(ctx context.Context, req *gamev1.GetRoomRPSChallengeRequest) (*gamev1.RoomRPSChallengeResponse, error)
	RetryRoomRPSSettlement(ctx context.Context, req *gamev1.RetryRoomRPSSettlementRequest) (*gamev1.RoomRPSChallengeResponse, error)
	ExpireRoomRPSChallenge(ctx context.Context, req *gamev1.ExpireRoomRPSChallengeRequest) (*gamev1.RoomRPSChallengeResponse, error)
}

type GRPCClient struct {
	client gamev1.GameAdminServiceClient
}

func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient {
	return &GRPCClient{client: gamev1.NewGameAdminServiceClient(conn)}
}

func (c *GRPCClient) ListPlatforms(ctx context.Context, req *gamev1.ListPlatformsRequest) (*gamev1.ListPlatformsResponse, error) {
	return c.client.ListPlatforms(ctx, req)
}

func (c *GRPCClient) UpsertPlatform(ctx context.Context, req *gamev1.UpsertPlatformRequest) (*gamev1.PlatformResponse, error) {
	return c.client.UpsertPlatform(ctx, req)
}

func (c *GRPCClient) ListCatalog(ctx context.Context, req *gamev1.ListCatalogRequest) (*gamev1.ListCatalogResponse, error) {
	return c.client.ListCatalog(ctx, req)
}

func (c *GRPCClient) UpsertCatalog(ctx context.Context, req *gamev1.UpsertCatalogRequest) (*gamev1.CatalogResponse, error) {
	return c.client.UpsertCatalog(ctx, req)
}

func (c *GRPCClient) SetGameStatus(ctx context.Context, req *gamev1.SetGameStatusRequest) (*gamev1.CatalogResponse, error) {
	return c.client.SetGameStatus(ctx, req)
}

func (c *GRPCClient) DeleteCatalog(ctx context.Context, req *gamev1.DeleteCatalogRequest) (*gamev1.DeleteCatalogResponse, error) {
	return c.client.DeleteCatalog(ctx, req)
}

func (c *GRPCClient) SetGameWhitelistEnabled(ctx context.Context, req *gamev1.SetGameWhitelistEnabledRequest) (*gamev1.CatalogResponse, error) {
	return c.client.SetGameWhitelistEnabled(ctx, req)
}

func (c *GRPCClient) ListGameWhitelistUsers(ctx context.Context, req *gamev1.ListGameWhitelistUsersRequest) (*gamev1.ListGameWhitelistUsersResponse, error) {
	return c.client.ListGameWhitelistUsers(ctx, req)
}

func (c *GRPCClient) AddGameWhitelistUser(ctx context.Context, req *gamev1.AddGameWhitelistUserRequest) (*gamev1.GameWhitelistUserResponse, error) {
	return c.client.AddGameWhitelistUser(ctx, req)
}

func (c *GRPCClient) DeleteGameWhitelistUser(ctx context.Context, req *gamev1.DeleteGameWhitelistUserRequest) (*gamev1.DeleteGameWhitelistUserResponse, error) {
	return c.client.DeleteGameWhitelistUser(ctx, req)
}

func (c *GRPCClient) ListSelfGames(ctx context.Context, req *gamev1.ListSelfGamesRequest) (*gamev1.ListSelfGamesResponse, error) {
	return c.client.ListSelfGames(ctx, req)
}

func (c *GRPCClient) UpdateDiceConfig(ctx context.Context, req *gamev1.UpdateDiceConfigRequest) (*gamev1.DiceConfigResponse, error) {
	return c.client.UpdateDiceConfig(ctx, req)
}

func (c *GRPCClient) GetSelfGameNewUserPolicy(ctx context.Context, req *gamev1.GetSelfGameNewUserPolicyRequest) (*gamev1.SelfGameNewUserPolicyResponse, error) {
	return c.client.GetSelfGameNewUserPolicy(ctx, req)
}

func (c *GRPCClient) UpdateSelfGameNewUserPolicy(ctx context.Context, req *gamev1.UpdateSelfGameNewUserPolicyRequest) (*gamev1.SelfGameNewUserPolicyResponse, error) {
	return c.client.UpdateSelfGameNewUserPolicy(ctx, req)
}

func (c *GRPCClient) ListSelfGameStakePools(ctx context.Context, req *gamev1.ListSelfGameStakePoolsRequest) (*gamev1.ListSelfGameStakePoolsResponse, error) {
	return c.client.ListSelfGameStakePools(ctx, req)
}

func (c *GRPCClient) UpdateSelfGameStakePool(ctx context.Context, req *gamev1.UpdateSelfGameStakePoolRequest) (*gamev1.SelfGameStakePoolResponse, error) {
	return c.client.UpdateSelfGameStakePool(ctx, req)
}

func (c *GRPCClient) AdjustSelfGameStakePool(ctx context.Context, req *gamev1.AdjustSelfGameStakePoolRequest) (*gamev1.AdjustSelfGameStakePoolResponse, error) {
	return c.client.AdjustSelfGameStakePool(ctx, req)
}

func (c *GRPCClient) ListDiceRobots(ctx context.Context, req *gamev1.ListDiceRobotsRequest) (*gamev1.ListDiceRobotsResponse, error) {
	return c.client.ListDiceRobots(ctx, req)
}

func (c *GRPCClient) RegisterDiceRobots(ctx context.Context, req *gamev1.RegisterDiceRobotsRequest) (*gamev1.RegisterDiceRobotsResponse, error) {
	return c.client.RegisterDiceRobots(ctx, req)
}

func (c *GRPCClient) SetDiceRobotStatus(ctx context.Context, req *gamev1.SetDiceRobotStatusRequest) (*gamev1.DiceRobotResponse, error) {
	return c.client.SetDiceRobotStatus(ctx, req)
}

// DeleteDiceRobot 透传后台删除机器人登记 RPC；admin-server 不直接操作 game-service 的机器人表。
func (c *GRPCClient) DeleteDiceRobot(ctx context.Context, req *gamev1.DeleteDiceRobotRequest) (*gamev1.DeleteDiceRobotResponse, error) {
	return c.client.DeleteDiceRobot(ctx, req)
}

func (c *GRPCClient) GetRoomRPSConfig(ctx context.Context, req *gamev1.GetRoomRPSConfigRequest) (*gamev1.RoomRPSConfigResponse, error) {
	// admin-server 不持有房内猜拳配置缓存；每次查询都透传到 game-service，保证后台看到的是运行时同一份配置事实。
	return c.client.GetRoomRPSConfig(ctx, req)
}

func (c *GRPCClient) UpdateRoomRPSConfig(ctx context.Context, req *gamev1.UpdateRoomRPSConfigRequest) (*gamev1.RoomRPSConfigResponse, error) {
	// 配置更新只通过 game-service 管理 RPC 落地，admin-server 不直接写游戏表，避免与运行时读取路径产生双写分叉。
	return c.client.UpdateRoomRPSConfig(ctx, req)
}

func (c *GRPCClient) ListRoomRPSChallenges(ctx context.Context, req *gamev1.ListRoomRPSChallengesRequest) (*gamev1.ListRoomRPSChallengesResponse, error) {
	// 订单列表筛选条件原样交给 game-service；后台不拼 SQL，也不自行解释 challenge 状态机。
	return c.client.ListRoomRPSChallenges(ctx, req)
}

func (c *GRPCClient) GetRoomRPSChallenge(ctx context.Context, req *gamev1.GetRoomRPSChallengeRequest) (*gamev1.RoomRPSChallengeResponse, error) {
	// 订单详情以 game-service 的单据快照为准，避免 admin-server 用列表缓存展示过期结算状态。
	return c.client.GetRoomRPSChallenge(ctx, req)
}

func (c *GRPCClient) RetryRoomRPSSettlement(ctx context.Context, req *gamev1.RetryRoomRPSSettlementRequest) (*gamev1.RoomRPSChallengeResponse, error) {
	// 重试结算是运维命令，不是后台本地状态修改；是否可重试必须由 game-service 在钱包幂等语义下判断。
	return c.client.RetryRoomRPSSettlement(ctx, req)
}

func (c *GRPCClient) ExpireRoomRPSChallenge(ctx context.Context, req *gamev1.ExpireRoomRPSChallengeRequest) (*gamev1.RoomRPSChallengeResponse, error) {
	// 手动过期同样只发命令给 game-service；pending 校验和并发应战保护必须在订单事务内完成。
	return c.client.ExpireRoomRPSChallenge(ctx, req)
}
