package exec

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/apiclient"
)

func TestProfileHandlerUsesTypedRequestAndAuthorizedContext(t *testing.T) {
	workDir := t.TempDir()
	require.NoError(t, os.WriteFile(filepath.Join(workDir, "avatar.png"), imageFixture("image/png"), 0o644))

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Equal(t, "/api/v1/workspaces/workspace-1/agents/server-agent-1/runtime/avatar", r.URL.Path)
		part, err := r.MultipartReader()
		require.NoError(t, err)
		file, err := part.NextPart()
		require.NoError(t, err)
		require.Equal(t, "avatar.png", file.FileName())
		_, err = io.ReadAll(file)
		require.NoError(t, err)
		_, _ = io.WriteString(w, `{"avatarUrl":"https://example.com/avatar.png"}`)
	}))
	t.Cleanup(server.Close)

	result, err := (profileHandler{}).setAvatar(context.Background(), actionScopedJSON[profileSetAvatarRequest]{
		Authorized: runtimeAuthorization{
			WorkDir: workDir,
			Server: &apiclient.Client{
				ServerURL: server.URL, RouteWorkspaceID: "workspace-1",
				AgentID: "server-agent-1", AuthToken: "server-token", HTTPClient: server.Client(),
			},
		},
		Body: profileSetAvatarRequest{ImagePath: "avatar.png"},
	})
	require.NoError(t, err)
	require.Equal(t, "https://example.com/avatar.png", result.Data.AvatarURL)
}

func TestProfileHandlerRejectsMissingFilePath(t *testing.T) {
	_, err := (profileHandler{}).setAvatar(context.Background(), actionScopedJSON[profileSetAvatarRequest]{})
	require.Error(t, err)
	require.Equal(t, CodeValidation, classify(err).Code)
}

func TestProfileHandlerRejectsMalformedAvatarResponse(t *testing.T) {
	workDir := t.TempDir()
	require.NoError(t, os.WriteFile(filepath.Join(workDir, "avatar.png"), imageFixture("image/png"), 0o644))
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		_, _ = io.WriteString(w, `{`)
	}))
	t.Cleanup(server.Close)

	_, err := (profileHandler{}).setAvatar(context.Background(), actionScopedJSON[profileSetAvatarRequest]{
		Authorized: runtimeAuthorization{
			WorkDir: workDir,
			Server: &apiclient.Client{
				ServerURL: server.URL, RouteWorkspaceID: "workspace-1",
				AgentID: "server-agent-1", AuthToken: "server-token", HTTPClient: server.Client(),
			},
		},
		Body: profileSetAvatarRequest{ImagePath: "avatar.png"},
	})
	require.Error(t, err)
	require.Equal(t, CodeInternal, classify(err).Code)
}

func TestProfileSchemaUsesImagePath(t *testing.T) {
	descriptor, err := describe(profileSetAvatarSpec)
	require.NoError(t, err)
	require.Contains(t, string(descriptor.InputSchema), `"imagePath"`)
	require.NotContains(t, string(descriptor.InputSchema), `"file_path"`)
	schema := mustCompile(t, descriptor.InputSchema)
	require.NoError(t, validateInstance(schema, json.RawMessage(`{"imagePath":"avatar.png"}`)))
	require.Error(t, validateInstance(schema, json.RawMessage(`{"imagePath":"   "}`)))
}
