package wire

import (
	"context"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/profile"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

func TestResolveRuntimeAttachmentsDownloadsToFileURI(t *testing.T) {
	t.Setenv(profile.ConfigDirEnvKey, t.TempDir())

	const body = "not really png"
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Equal(t, "/api/v1/workspaces/wsp_1/attachments/att_img", r.URL.Path)
		w.Header().Set("Content-Type", "image/png")
		_, _ = w.Write([]byte(body))
	}))
	defer server.Close()

	ch := &Protocol{
		serverURL:   server.URL,
		authToken:   "token",
		httpClient:  server.Client(),
		workspaceID: "wsp_1",
	}

	got, err := ch.ResolveRuntimeAttachments(context.Background(), "agent-1", []types.MessageAttachment{
		{ID: "att_img", Filename: "image.png"},
	})

	require.NoError(t, err)
	require.Len(t, got, 1)
	require.Equal(t, "att_img", got[0].ID)
	require.Equal(t, "image.png", got[0].Filename)
	require.Equal(t, "image/png", got[0].MIME)
	require.Equal(t, int64(len(body)), got[0].Size)
	require.NotEmpty(t, got[0].Path)

	uri, err := url.Parse(got[0].URI)
	require.NoError(t, err)
	require.Equal(t, "file", uri.Scheme)
	require.Equal(t, got[0].Path, uri.Path)
	data, err := os.ReadFile(uri.Path)
	require.NoError(t, err)
	require.Equal(t, body, string(data))
}

func TestResolveRuntimeAttachmentsUsesDownloadFilenameMetadata(t *testing.T) {
	t.Setenv(profile.ConfigDirEnvKey, t.TempDir())

	const body = "name,email\nAda,ada@example.com\n"
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Equal(t, "/api/v1/workspaces/wsp_1/attachments/att_csv", r.URL.Path)
		w.Header().Set("Content-Type", "application/octet-stream")
		w.Header().Set("Content-Disposition", `attachment; filename="registrations.csv"`)
		_, _ = w.Write([]byte(body))
	}))
	defer server.Close()

	ch := &Protocol{
		serverURL:   server.URL,
		authToken:   "token",
		httpClient:  server.Client(),
		workspaceID: "wsp_1",
	}

	got, err := ch.ResolveRuntimeAttachments(context.Background(), "agent-1", []types.MessageAttachment{
		{ID: "att_csv"},
	})

	require.NoError(t, err)
	require.Len(t, got, 1)
	require.Equal(t, "registrations.csv", got[0].Filename)
	require.Equal(t, "text/csv; charset=utf-8", got[0].MIME)

	uri, err := url.Parse(got[0].URI)
	require.NoError(t, err)
	require.Equal(t, ".csv", filepath.Ext(uri.Path))
}

func TestResolveRuntimeAttachmentsPreservesMessageMetadataForCachedFile(t *testing.T) {
	cacheRoot := t.TempDir()
	t.Setenv(profile.ConfigDirEnvKey, cacheRoot)

	cacheDir := filepath.Join(cacheRoot, "attachments")
	require.NoError(t, os.MkdirAll(cacheDir, 0755))
	cachedPath := filepath.Join(cacheDir, "att_doc.xlsx")
	require.NoError(t, os.WriteFile(cachedPath, []byte("cached"), 0644))

	ch := &Protocol{}
	got, err := ch.ResolveRuntimeAttachments(context.Background(), "agent-1", []types.MessageAttachment{
		{
			ID:          "att_doc",
			Filename:    "registrations.xlsx",
			ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
			SizeBytes:   123,
		},
	})

	require.NoError(t, err)
	require.Len(t, got, 1)
	require.Equal(t, "registrations.xlsx", got[0].Filename)
	require.Equal(t, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", got[0].MIME)
	require.Equal(t, int64(6), got[0].Size)
	require.Equal(t, cachedPath, got[0].Path)
}
