package regionalapi

import (
	"context"

	replay_v1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"
	"github.com/tidbcloud/pkgv2/bizerr"
)

const (
	createReplayPath = "/cluster-server/api/v1/replays"
	getReplayPath    = "/cluster-server/api/v1/replays/{replay_id}"
	updateReplayPath = "/cluster-server/api/v1/replays/{replay_id}"
	deleteReplayPath = "/cluster-server/api/v1/replays/{replay_id}"
	startReplayPath  = "/cluster-server/api/v1/replays/{replay_id}:start"
	stopReplayPath   = "/cluster-server/api/v1/replays/{replay_id}:stop"
)

const (
	replayIDPathParam = "replay_id"
)

type ReplayClientImpl struct {
	regionalCli RegionalClient
}

func NewReplayClient(regionalCli RegionalClient) ReplayClient {
	return &ReplayClientImpl{
		regionalCli: regionalCli,
	}
}

func (m *ReplayClientImpl) CreateReplay(
	ctx context.Context, region *Region, req *replay_v1.CreateReplayRequest,
) (*replay_v1.Replay, bizerr.BizError) {
	replay := new(replay_v1.Replay)
	if err := m.regionalCli.Post(
		ctx, region, createReplayPath, nil, nil, req, replay); err != nil {
		return nil, err
	}
	return replay, nil
}

func (m *ReplayClientImpl) GetReplay(
	ctx context.Context, region *Region, req *replay_v1.GetReplayRequest,
) (*replay_v1.GetReplayResponse, bizerr.BizError) {
	pathParams := map[string]string{
		replayIDPathParam: req.ReplayId,
	}
	resp := new(replay_v1.GetReplayResponse)
	if err := m.regionalCli.Get(ctx, region, getReplayPath, pathParams, nil, resp); err != nil {
		return nil, err
	}
	return resp, nil
}

func (m *ReplayClientImpl) UpdateReplay(
	ctx context.Context, region *Region, req *replay_v1.UpdateReplayRequest,
) (*replay_v1.Replay, bizerr.BizError) {
	pathParams := map[string]string{
		replayIDPathParam: req.Replay.ReplayId,
	}
	replay := new(replay_v1.Replay)
	if err := m.regionalCli.Post(
		ctx, region, updateReplayPath, pathParams, nil, req, replay); err != nil {
		return nil, err
	}
	return replay, nil
}

func (m *ReplayClientImpl) DeleteReplay(
	ctx context.Context, region *Region, req *replay_v1.DeleteReplayRequest,
) (*replay_v1.Replay, bizerr.BizError) {
	pathParams := map[string]string{
		replayIDPathParam: req.ReplayId,
	}
	replay := new(replay_v1.Replay)
	if err := m.regionalCli.Delete(ctx, region, deleteReplayPath, pathParams, nil); err != nil {
		return nil, err
	}
	return replay, nil
}

func (m *ReplayClientImpl) StartReplay(
	ctx context.Context, region *Region, req *replay_v1.StartReplayRequest,
) (*replay_v1.Replay, bizerr.BizError) {
	pathParams := map[string]string{
		replayIDPathParam: req.ReplayId,
	}
	replay := new(replay_v1.Replay)
	if err := m.regionalCli.Post(ctx, region, startReplayPath, pathParams, nil, nil, replay); err != nil {
		return nil, err
	}
	return replay, nil
}

func (m *ReplayClientImpl) StopReplay(
	ctx context.Context, region *Region, req *replay_v1.StopReplayRequest,
) (*replay_v1.Replay, bizerr.BizError) {
	pathParams := map[string]string{
		replayIDPathParam: req.ReplayId,
	}
	replay := new(replay_v1.Replay)
	if err := m.regionalCli.Post(ctx, region, stopReplayPath, pathParams, nil, nil, replay); err != nil {
		return nil, err
	}
	return replay, nil
}
