package external

import (
	"fmt"
	"log"
	"ticket-pimp/internal/domain"
	"ticket-pimp/internal/helpers"
	"time"
)

type Git struct {
	*CommonClient
	conf *domain.GitConfig
}

func NewGit(conf domain.GitConfig) *Git {
	headers := map[string]string{
		"Accept":               "application/vnd.github+json",
		"Authorization":        "Token " + conf.Token,
		"X-GitHub-Api-Version": "2022-11-28",
		"Content-Type":         "application/json",
	}

	client := NewClient().
		SetTimeout(5 * time.Second).
		SetCommonHeaders(headers).
		SetBaseURL(conf.BaseUrl)

	return &Git{
		CommonClient: &CommonClient{client},
		conf:         &conf,
	}
}

func (gb *Git) CreateRepo(name string) (*domain.Git, error) {
	//Create git repository with iGit interface;
	repo, err := gb.newRepo(name)
	if err != nil {
		return nil, err
	}

	//Set 'apps' as collaborator to created repository;
	_, err = gb.defaultGroupAsCollaborator(repo)
	if err != nil {
		return nil, err
	}

	return repo, nil
}

type gitCreateRequest struct {
	Name    string `json:"name"`
	Private bool   `json:"private"`
}

func (gb *Git) newRepo(name string) (*domain.Git, error) {
	name = helpers.Cut(name)

	payload := gitCreateRequest{
		Name:    name,
		Private: true,
	}

	var git domain.Git

	resp, _ := gb.R().
		SetBody(&payload).
		SetSuccessResult(&git).
		Post(fmt.Sprintf("/orgs/%s/repos", gb.conf.OrgName))

	if resp.Err != nil {
		log.Print(resp.Status, resp.Err)
		return nil, resp.Err
	}

	return &git, nil
}

type gitSetPermissionRequest struct {
	Perm string `json:"permission"`
}

func (gb *Git) defaultGroupAsCollaborator(git *domain.Git) (*domain.Git, error) {

	payload := gitSetPermissionRequest{
		Perm: "push",
	}

	respURL := fmt.Sprintf("/orgs/%s/teams/devs/repos/%s/%s", gb.conf.OrgName, gb.conf.OrgName, git.Name)

	resp, _ := gb.R().
		SetBody(&payload).
		Put(respURL)

	if resp.Err != nil {
		log.Print(resp.Err)
		return nil, resp.Err
	}

	return git, nil
}
