package cmd

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/spf13/viper"
)

func TestCallAPI(t *testing.T) {
	tests := []struct {
		name          string
		responseBody  string
		statusCode    int
		expectedError string
		shouldError   bool
	}{
		{
			name:          "successful API call",
			responseBody:  `{"version": "3.25.0"}`,
			statusCode:    200,
			expectedError: "",
			shouldError:   false,
		},
		{
			name:          "server returns 404",
			responseBody:  "",
			statusCode:    404,
			expectedError: "invalid server endpoint (404)",
			shouldError:   true,
		},
		{
			name:          "server returns 401",
			responseBody:  "",
			statusCode:    401,
			expectedError: "invalid credentials (401)",
			shouldError:   true,
		},
		{
			name:          "server returns 500",
			responseBody:  "",
			statusCode:    500,
			expectedError: "http error from server (500)",
			shouldError:   true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create a mock HTTP server
			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				// Verify authentication header is present
				auth := r.Header.Get("X-Cavaliba-Key")
				if auth == "" {
					t.Error("expected X-Cavaliba-Key header to be set")
				}

				w.WriteHeader(tt.statusCode)
				fmt.Fprint(w, tt.responseBody)
			}))
			defer server.Close()

			// Configure viper for the test
			viper.Set("client_id", "test_id")
			viper.Set("client_secret", "test_secret")

			// Create API target
			target := APITarget{
				url:            server.URL + "/test/",
				ssl_skipverify: false,
			}

			// Call API
			result, err := CallAPI(target)

			// Check for errors
			if tt.shouldError {
				if err == nil {
					t.Errorf("expected error containing %q, got nil", tt.expectedError)
				} else if !strings.Contains(err.Error(), tt.expectedError) {
					t.Errorf("expected error containing %q, got %q", tt.expectedError, err.Error())
				}
			} else {
				if err != nil {
					t.Errorf("expected no error, got %q", err.Error())
				}
				if result.body != tt.responseBody {
					t.Errorf("expected body %q, got %q", tt.responseBody, result.body)
				}
				if result.http_code != tt.statusCode {
					t.Errorf("expected status code %d, got %d", tt.statusCode, result.http_code)
				}
			}
		})
	}
}

func TestPrintVerbose(t *testing.T) {
	tests := []struct {
		name     string
		verbose  bool
		expected string
	}{
		{
			name:     "verbose enabled",
			verbose:  true,
			expected: "----- API Request -----",
		},
		{
			name:     "verbose disabled",
			verbose:  false,
			expected: "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			verbose = tt.verbose

			target := APITarget{
				url:            "http://localhost:8000/test/",
				ssl_skipverify: false,
			}

			PrintVerboseTarget(target)

			result := APIResult{
				http_code:    200,
				body:         `{"status": "OK"}`,
				content_type: "application/json",
			}

			// Call PrintVerbose - just verify it doesn't panic
			PrintVerboseResult(result)

			verbose = false
		})
	}
}
