package web

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestHandleModalAPI_Shutdown(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=shutdown", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Close MPV.Rocks Installer" {
		t.Errorf("Expected title 'Close MPV.Rocks Installer', got '%s'", config.Title)
	}

	if config.Danger != true {
		t.Errorf("Expected danger to be true for shutdown")
	}
}

func TestHandleModalAPI_UpdateManager(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=update-manager&version=1.2.3", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Update MPV Manager" {
		t.Errorf("Expected title 'Update MPV Manager', got '%s'", config.Title)
	}

	if config.Message != "Update MPV Manager to version 1.2.3?" {
		t.Errorf("Expected message 'Update MPV Manager to version 1.2.3?', got '%s'", config.Message)
	}

	if config.Danger != false {
		t.Errorf("Expected danger to be false for update manager")
	}
}

func TestHandleModalAPI_UpdateManagerSuccess(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=update-manager-success", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Update Successful!" {
		t.Errorf("Expected title 'Update Successful!', got '%s'", config.Title)
	}

	if config.ConfirmText != "Close & Exit" {
		t.Errorf("Expected confirm text 'Close & Exit', got '%s'", config.ConfirmText)
	}

	if config.CancelText != "" {
		t.Errorf("Expected cancel text to be empty, got '%s'", config.CancelText)
	}

	if config.ConfirmURL != "/api/shutdown" {
		t.Errorf("Expected confirm URL '/api/shutdown', got '%s'", config.ConfirmURL)
	}

	if config.Success != true {
		t.Errorf("Expected success to be true for update manager success modal")
	}

	if config.Danger != false {
		t.Errorf("Expected danger to be false for update manager success modal")
	}
}

func TestHandleModalAPI_Uninstall(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=uninstall&app_name=mpv", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Uninstall App" {
		t.Errorf("Expected title 'Uninstall App', got '%s'", config.Title)
	}

	if config.Message != "Are you sure you want to uninstall mpv?" {
		t.Errorf("Expected message 'Are you sure you want to uninstall mpv?', got '%s'", config.Message)
	}

	if config.Danger != true {
		t.Errorf("Expected danger to be true for uninstall")
	}
}

func TestHandleModalAPI_RemoveFileAssociations(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=remove-file-associations", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Remove File Associations" {
		t.Errorf("Expected title 'Remove File Associations', got '%s'", config.Title)
	}

	if config.Danger != true {
		t.Errorf("Expected danger to be true for remove file associations")
	}
}

func TestHandleModalAPI_ResetConfig(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=reset-config", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Reset MPV Config" {
		t.Errorf("Expected title 'Reset MPV Config', got '%s'", config.Title)
	}

	if config.Danger != true {
		t.Errorf("Expected danger to be true for reset config")
	}
}

func TestHandleModalAPI_RestoreConfig(t *testing.T) {
	// Use a valid backup path that matches the expected pattern: YYYY-MM-DD-HHMMSS_mpv.conf
	// Note: This test will fail with 400 because the path doesn't actually exist in the filesystem,
	// but that's expected behavior for the validation. We're testing that the API handles validation correctly.
	server := &Server{}
	backupPath := "2026-01-31-123456_mpv.conf"
	req := httptest.NewRequest("GET", "/api/modal?type=restore-config&backup_path="+backupPath, nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	// The test now expects 400 because validation will fail (path doesn't exist on filesystem)
	// This is the correct behavior - we validate the path before proceeding
	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected status Bad Request (400), got %d", w.Code)
	}
}

func TestHandleModalAPI_ApplyConfig(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=apply-config", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusOK {
		t.Errorf("Expected status OK, got %d", w.Code)
	}

	var config ModalConfig
	err := json.Unmarshal(w.Body.Bytes(), &config)
	if err != nil {
		t.Fatalf("Failed to parse JSON: %v", err)
	}

	if config.Title != "Apply Configuration Settings" {
		t.Errorf("Expected title 'Apply Configuration Settings', got '%s'", config.Title)
	}

	if config.Danger != false {
		t.Errorf("Expected danger to be false for apply config")
	}
}

func TestHandleModalAPI_MissingType(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected status Bad Request, got %d", w.Code)
	}
}

func TestHandleModalAPI_UnknownType(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=unknown-type", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected status Bad Request, got %d", w.Code)
	}
}

func TestHandleModalAPI_MissingUninstallParams(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=uninstall", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected status Bad Request, got %d", w.Code)
	}
}

func TestHandleModalAPI_MissingRestoreParams(t *testing.T) {
	server := &Server{}
	req := httptest.NewRequest("GET", "/api/modal?type=restore-config", nil)
	w := httptest.NewRecorder()

	server.handleModalAPI(w, req)

	if w.Code != http.StatusBadRequest {
		t.Errorf("Expected status Bad Request, got %d", w.Code)
	}
}

func TestModalConfig_JSONSerialization(t *testing.T) {
	config := ModalConfig{
		Title:       "Test Title",
		Message:     "Test Message",
		ConfirmText: "Confirm",
		CancelText:  "Cancel",
		ConfirmURL:  "/api/test",
		ConfirmData: `{"key": "value"}`,
		Danger:      true,
	}

	data, err := json.Marshal(config)
	if err != nil {
		t.Fatalf("Failed to marshal JSON: %v", err)
	}

	var decoded ModalConfig
	err = json.Unmarshal(data, &decoded)
	if err != nil {
		t.Fatalf("Failed to unmarshal JSON: %v", err)
	}

	if decoded.Title != config.Title {
		t.Errorf("Title mismatch: got %s, want %s", decoded.Title, config.Title)
	}

	if decoded.Danger != config.Danger {
		t.Errorf("Danger mismatch: got %v, want %v", decoded.Danger, config.Danger)
	}
}
