//go:generate ${GOBIN}/mockgen -destination client_mock.go -package=oncallcli ${GO_MODULE}/pkg/infra/clients/oncallcli Client
package oncallcli

import (
	"context"
	"fmt"
	"net/http"
	"strconv"

	"github.com/go-resty/resty/v2"
)

type Client interface {
	GetCurrentOnCall(ctx context.Context, teamRef string) (*CurrentOnCallResponse, error)
	GetSchedule(ctx context.Context, param GetScheduleParam) (*ScheduleResponse, error)
	GetOverview(ctx context.Context) ([]OverviewTeam, error)
}

type client struct {
	raw *resty.Client
}

func NewClient(addr string, serviceKey string) (Client, error) {
	raw := resty.New().
		SetTransport(http.DefaultTransport).
		SetBaseURL(addr).
		OnBeforeRequest(func(c *resty.Client, r *resty.Request) error {
			r.Header.Set("Authorization", "Bearer "+serviceKey)
			return nil
		}).
		OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
			if !r.IsSuccess() {
				return fmt.Errorf("oncall service error, status: %s, body: %s", r.Status(), string(r.Body()))
			}
			return nil
		})

	return &client{raw: raw}, nil
}

func (c *client) GetCurrentOnCall(ctx context.Context, teamRef string) (*CurrentOnCallResponse, error) {
	resp := &CurrentOnCallResponse{}
	_, err := c.raw.R().
		SetContext(ctx).
		SetPathParam("ref", teamRef).
		SetResult(resp).
		Get("/api/v1/teams/{ref}/current-oncall")
	if err != nil {
		return nil, fmt.Errorf("get current oncall failed: %w", err)
	}
	return resp, nil
}

func (c *client) GetOverview(ctx context.Context) ([]OverviewTeam, error) {
	var resp []OverviewTeam
	_, err := c.raw.R().
		SetContext(ctx).
		SetResult(&resp).
		Get("/api/v1/schedule/overview")
	if err != nil {
		return nil, fmt.Errorf("get overview failed: %w", err)
	}
	return resp, nil
}

func (c *client) GetSchedule(ctx context.Context, param GetScheduleParam) (*ScheduleResponse, error) {
	resp := &ScheduleResponse{}
	_, err := c.raw.R().
		SetContext(ctx).
		SetQueryParam("team_id", strconv.Itoa(param.TeamID)).
		SetQueryParam("start_time", strconv.FormatInt(param.StartTime, 10)).
		SetQueryParam("end_time", strconv.FormatInt(param.EndTime, 10)).
		SetResult(resp).
		Get("/api/v1/schedule")
	if err != nil {
		return nil, fmt.Errorf("get schedule failed: %w", err)
	}
	return resp, nil
}
