package jenkins

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

	"freeleaps.com/gitea-webhook-ambassador/internal/logger"
)

// Client represents a Jenkins API client
type Client struct {
	url      string
	username string
	token    string
	client   *http.Client
}

// Config represents Jenkins client configuration
type Config struct {
	URL      string
	Username string
	Token    string
	Timeout  time.Duration
}

// JobParameters represents parameters to pass to a Jenkins job
type JobParameters map[string]string

// New creates a new Jenkins client
func New(config Config) *Client {
	return &Client{
		url:      config.URL,
		username: config.Username,
		token:    config.Token,
		client: &http.Client{
			Timeout: config.Timeout,
		},
	}
}

// TriggerJob triggers a Jenkins job with the given parameters
func (c *Client) TriggerJob(jobName string, parameters map[string]string) error {
	// Build request URL
	url := fmt.Sprintf("%s/job/%s/buildWithParameters", c.url, jobName)

	// Create request body
	body, err := json.Marshal(parameters)
	if err != nil {
		return fmt.Errorf("failed to marshal parameters: %v", err)
	}

	// Create request
	req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body))
	if err != nil {
		return fmt.Errorf("failed to create request: %v", err)
	}

	// Set headers
	req.Header.Set("Content-Type", "application/json")
	req.SetBasicAuth(c.username, c.token)

	// Send request
	resp, err := c.client.Do(req)
	if err != nil {
		return fmt.Errorf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	// Check response status
	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("unexpected status code: %d, body: %s", resp.StatusCode, string(body))
	}

	return nil
}

// IsConnected checks if Jenkins is accessible
func (c *Client) IsConnected() bool {
	// Try to access Jenkins API
	url := fmt.Sprintf("%s/api/json", c.url)
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		logger.Error("Failed to create Jenkins request: %v", err)
		return false
	}

	req.SetBasicAuth(c.username, c.token)
	resp, err := c.client.Do(req)
	if err != nil {
		logger.Error("Failed to connect to Jenkins: %v", err)
		return false
	}
	defer resp.Body.Close()

	return resp.StatusCode == http.StatusOK
}
