package wire

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"

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

// ResolveRuntimeAttachments resolves AgentTeam message attachments into local file
// URIs that runtime drivers can pass to their native file-input protocols.
func (c *Protocol) ResolveRuntimeAttachments(ctx context.Context, serverAgentID string, attachments []types.MessageAttachment) ([]types.RuntimeAttachment, error) {
	attachments = types.NormalizeMessageAttachments(attachments)
	if len(attachments) == 0 {
		return nil, nil
	}
	api := c.APIClient(strings.TrimSpace(serverAgentID))
	resolved := make([]types.RuntimeAttachment, 0, len(attachments))
	for _, attachment := range attachments {
		if strings.TrimSpace(attachment.ID) == "" {
			continue
		}
		item, err := resolveAgentTeamRuntimeAttachment(ctx, api, attachment)
		if err != nil {
			return nil, err
		}
		resolved = append(resolved, item)
	}
	if len(resolved) == 0 {
		return nil, nil
	}
	return resolved, nil
}

func resolveAgentTeamRuntimeAttachment(ctx context.Context, api *apiclient.Client, attachment types.MessageAttachment) (types.RuntimeAttachment, error) {
	if api == nil {
		return types.RuntimeAttachment{}, fmt.Errorf("agentteam API not available")
	}
	id := strings.TrimSpace(attachment.ID)
	if id == "" {
		return types.RuntimeAttachment{}, fmt.Errorf("attachment id is required")
	}

	cacheDir := runtimeattachments.CacheDir(profile.ConfigDir())
	if cachedPath, ok := runtimeattachments.FindCachedPath(cacheDir, id); ok {
		return runtimeattachments.FromPath(attachment, cachedPath, ""), nil
	}

	download, err := api.GetAttachment(ctx, id)
	if err != nil {
		return types.RuntimeAttachment{}, err
	}
	filename := strings.TrimSpace(attachment.Filename)
	if filename == "" {
		filename = strings.TrimSpace(download.Filename)
	}
	contentType := runtimeattachments.NormalizeMIME(download.ContentType, filename, download.Data)
	if err := os.MkdirAll(cacheDir, runtimeattachments.CacheDirMode); err != nil {
		return types.RuntimeAttachment{}, err
	}
	localPath := filepath.Join(cacheDir, runtimeattachments.CacheFilename(id, filename, contentType))
	if err := os.WriteFile(localPath, download.Data, runtimeattachments.CacheFileMode); err != nil {
		return types.RuntimeAttachment{}, err
	}
	attachment.Filename = filename
	return runtimeattachments.FromPath(attachment, localPath, contentType), nil
}
