package action

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log/slog"
	"net/http"
	"time"

	"github.com/tidbcloud/jiraport/pkg/entity"
)

type HTTPForwardCommand struct {
	logger *slog.Logger
}

func newHTTPForwardCommand(
	logger *slog.Logger,
) (*HTTPForwardCommand, error) {
	return &HTTPForwardCommand{
		logger: logger,
	}, nil
}

func (cmd *HTTPForwardCommand) Exec(ctx context.Context, actionExecInfo *entity.NotificationActionExecInfo, args ...string) (bool, string, error) {
	// get positional parameters
	method := "POST"
	address := ""
	if len(args) > 0 {
		method = args[0]
	}
	if len(args) > 1 {
		address = args[1]
	} else {
		return false, "", fmt.Errorf("http forward action need address parameter")
	}

	var bodyReader io.Reader
	if actionExecInfo != nil {
		b, err := json.Marshal(actionExecInfo.Notification.Issue)
		if err != nil {
			return false, "", fmt.Errorf("marshal actionExecInfo: %w", err)
		}
		bodyReader = bytes.NewReader(b)
	}

	req, err := http.NewRequestWithContext(ctx, method, address, bodyReader)
	if err != nil {
		return false, "", fmt.Errorf("create request: %w", err)
	}
	if bodyReader != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return false, "", fmt.Errorf("do request: %w", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return false, "", fmt.Errorf("read response: %w", err)
	}

	if resp.StatusCode >= 200 && resp.StatusCode < 300 {
		cmd.logger.Info("http forward success", "method", method, "address", address, "status", resp.Status)
		return true, string(respBody), nil
	}

	cmd.logger.Warn("http forward failed", "method", method, "address", address, "status", resp.Status)
	return false, string(respBody), fmt.Errorf("http request failed: %s", resp.Status)
}
