package app

import (
	"net/http"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/api/testkit/httputil"
	storeapp "github.com/tidbcloud/AgentTeam/internal/store/app"
)

func TestInstallationExtensionManagementRoutes(t *testing.T) {
	t.Parallel()

	now := time.Date(2026, 8, 11, 14, 0, 0, 0, time.UTC)
	digest := "sha256:9cf723b2faa16f3b58b8ff4442a3c5f3e77d6c466c5c521f8e54e8d5b7536fd3"
	fake := newFakeStore()
	fake.installationExtensions = []storeapp.InstallationExtensionView{{
		ID:                    "svcie_1",
		ExtensionName:         "github",
		DefinitionDomain:      "github",
		DefinitionVersion:     1,
		DefinitionDigest:      digest,
		DefinitionDisplayName: "GitHub",
		DefaultName:           "github",
		DefaultEnabled:        true,
		Selected:              true,
		Status:                "active",
		SelectionSource:       "app_default",
		CreatedAt:             now,
		UpdatedAt:             now,
	}}
	router := newAppRouter(Dependencies{AppStore: fake})

	resp := httputil.DoJSON(t, router, http.MethodGet, "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions", nil)
	require.Equal(t, http.StatusOK, resp.Code)
	require.JSONEq(t, `[{
		"id":"svcie_1",
		"extensionName":"github",
		"definition":{
			"domain":"github",
			"version":1,
			"digest":"`+digest+`",
			"displayName":"GitHub",
			"defaultName":"github",
			"defaultEnabled":true
		},
		"selected":true,
		"status":"active",
		"selectionSource":"app_default",
		"createdAt":"2026-08-11T14:00:00Z",
		"updatedAt":"2026-08-11T14:00:00Z"
	}]`, resp.Body.String())
	require.NotContains(t, resp.Body.String(), "workspaceId")
	require.NotContains(t, resp.Body.String(), "serviceDefinitionId")
	require.NotContains(t, resp.Body.String(), "serviceInstallationId")
	require.NotContains(t, resp.Body.String(), "credentials")

	resp = httputil.DoJSON(t, router, http.MethodPost, "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions", map[string]any{
		"definitionDomain": "github",
		"extensionName":    "github-watch",
	})
	require.Equal(t, http.StatusOK, resp.Code)
	require.Equal(t, "add", fake.lastExtensionOperation)
	require.Equal(t, "github", fake.lastExtensionDomain)
	require.Equal(t, "github-watch", fake.lastExtensionName)

	resp = httputil.DoJSON(t, router, http.MethodPatch, "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions/svcie_1", map[string]any{
		"extensionName": "github-watch",
	})
	require.Equal(t, http.StatusOK, resp.Code)
	require.Equal(t, "rename", fake.lastExtensionOperation)
	require.Equal(t, "svcie_1", fake.lastExtensionSelectionID)

	resp = httputil.DoJSON(t, router, http.MethodPatch, "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions/svcie_1", map[string]any{
		"enabled": true,
	})
	require.Equal(t, http.StatusOK, resp.Code)
	require.Equal(t, "enable", fake.lastExtensionOperation)

	resp = httputil.DoJSON(t, router, http.MethodDelete, "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions/svcie_1", nil)
	require.Equal(t, http.StatusOK, resp.Code)
	require.Equal(t, "disable", fake.lastExtensionOperation)
}

func TestInstallationExtensionPatchRequiresOneMutation(t *testing.T) {
	t.Parallel()

	fake := newFakeStore()
	router := newAppRouter(Dependencies{AppStore: fake})
	path := "/api/v1/workspaces/wsp_1/app-installations/appinst_direct_1/extensions/svcie_1"

	resp := httputil.DoJSON(t, router, http.MethodPatch, path, map[string]any{})
	require.Equal(t, http.StatusBadRequest, resp.Code)

	resp = httputil.DoJSON(t, router, http.MethodPatch, path, map[string]any{
		"extensionName": "github-watch",
		"enabled":       true,
	})
	require.Equal(t, http.StatusBadRequest, resp.Code)
}
