package jiracli

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"

	httputil "github.com/tidbcloud/escalation-base/support-autoshift/pkg/infra/utils/http"
)

type raw struct {
	scheme     string
	host       string
	rootPath   string
	project    string
	token      string
	httpClient *http.Client
}

func (cli *raw) GetRole(ctx context.Context, roleId string) (GetRoleResp, error) {
	url := cli.buildURL("/rest/api/2/project/"+cli.project+"/role/"+roleId, nil)
	resp := GetRoleResp{}
	err := cli.do(ctx, "GET", url.String(), nil, &resp)
	return resp, err
}

func (cli *raw) UpdateRoleActors(ctx context.Context, roleId string, emails []string) error {
	url := cli.buildURL("/rest/api/2/project/"+cli.project+"/role/"+roleId, nil)
	req := UpdateRoleReq{CategorisedActors: CategorisedActorsStruct{AtlassianUserRoleActor: emails}}
	resp := UpdateRoleResp{}
	err := cli.do(ctx, "PUT", url.String(), &req, &resp)
	return err
}

func (cli *raw) do(ctx context.Context, method, url string, req any, resp any) error {
	var bodyReader io.Reader
	if req != nil {
		jsonBytes, err := json.Marshal(req)
		if err != nil {
			return fmt.Errorf("marshal req failed: %w", err)
		}
		bodyReader = bytes.NewReader(jsonBytes)
	}

	httpReq, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("build req failed: %w", err)
	}

	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+cli.token)
	// HACK: use a fake user-agent to avoid block from ONCALL project
	httpReq.Header.Set("User-Agent", "Mozilla/5.0")

	err = httputil.DoSimply(cli.httpClient, httpReq, resp)
	if err != nil {
		return fmt.Errorf("request failed: %w", err)
	}

	return nil
}

func (cli *raw) buildURL(path string, query map[string]string) url.URL {
	u := url.URL{
		Scheme: cli.scheme,
		Host:   cli.host,
		Path:   cli.rootPath + path,
	}

	uQuery := u.Query()
	for k, v := range query {
		uQuery.Add(k, v)
	}
	u.RawQuery = uQuery.Encode()

	return u
}
