package validate

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

	"github.com/prometheus-community/jiralert/pkg/alertmanager"
	"github.com/prometheus-community/jiralert/pkg/client"
)

type ValidateAPIResp struct {
	UpdateAlert bool                   `json:"updateAlert"`
	Actions     map[string]interface{} `json:"actions"`
	Message     *string                `json:"message"`
}

func (v *ValidateHandler) validateByAPI(params map[string]interface{}, data *alertmanager.Data, issue *client.Issue) (comments []string, err error) {
	// Validate By API params REQUIRED:
	// comments := make([]string, 0)
	comments = append(comments, "precheck by API")
	debugComments := make([]string, 0)
	debugComments = append(debugComments, "---")
	debugComments = append(debugComments, "DEBUG INFO")
	defer func() {
		comments = append(comments, debugComments...)
	}()

	if apiURL, ok := params[`api`]; ok {
		str, ok := apiURL.(string)
		if !ok {
			return comments, fmt.Errorf("api URL is not of type string")
		}
		if len(data.Alerts) < 1 {
			return comments, fmt.Errorf("length of alerts is less than 1")
		}
		body, err := json.Marshal(data.Alerts[0])
		if err != nil {
			return comments, err
		}
		debugComments = append(debugComments, fmt.Sprintf("request url: %s", str))

		req, _ := http.NewRequest("POST", str, bytes.NewBuffer(body))
		var structRes ValidateAPIResp
		res, err := v.client.Do(req)
		if err != nil {
			return comments, err
		}
		defer res.Body.Close()

		resBody, err := io.ReadAll(res.Body)
		if err != nil {
			return comments, err
		}
		buffer := new(bytes.Buffer)
		if err := json.Compact(buffer, resBody); err != nil {
			return comments, err
		}
		debugComments = append(debugComments, fmt.Sprintf("response body: %s", buffer.String()))

		err = json.Unmarshal(resBody, &structRes)
		if err != nil {
			return comments, err
		}

		// update the issue.
		if structRes.UpdateAlert {
			// priority set
			if priority, ok := structRes.Actions[`priority`]; ok {
				priorityStr, ok := priority.(string)
				if !ok {
					return comments, fmt.Errorf("priority is not of type string")
				}
				err = validatePriority(priorityStr)
				if err != nil {
					return comments, err
				}
				issue.Priority = priorityStr
				comments = append(comments, fmt.Sprintf("Action: priority is set to %s", priorityStr))
			}
		}

	} else {
		return comments, fmt.Errorf("API field is not configured")
	}
	return comments, nil
}

func validatePriority(priority string) error {
	jiraPririty := []string{`Warning`, `Major`, `Critical`}
	for _, v := range jiraPririty {
		if v == priority {
			return nil
		}
	}
	return fmt.Errorf("cannot identify priority %s", priority)
}
