package wire

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/desktop/internal/agent"
)

type llmProxySessionRequest struct {
	SessionID      string `json:"sessionId,omitempty"`
	CredentialKind string `json:"credentialKind,omitempty"`
}

type llmProxySessionResponse struct {
	ProxyToken     string     `json:"proxyToken"`
	ExpiresAt      time.Time  `json:"expiresAt"`
	SessionID      string     `json:"sessionId"`
	RefreshAt      *time.Time `json:"refreshAt,omitempty"`
	MaasBaseURL    string     `json:"maasBaseURL,omitempty"`
	CredentialKind string     `json:"credentialKind,omitempty"`
}

type llmProxySessionIssuer struct {
	channel        *Protocol
	serverAgentID  string
	credentialKind string
}

// LLMProxySessionIssuer returns a MaaS capability issuer bound to one AgentTeam agent.
func (c *Protocol) LLMProxySessionIssuer(serverAgentID string, credentialKind ...string) agent.AgentTeamLLMProxySessionIssuer {
	if c == nil || strings.TrimSpace(serverAgentID) == "" {
		return nil
	}
	var kind string
	if len(credentialKind) > 0 {
		kind = strings.TrimSpace(credentialKind[0])
	}
	return &llmProxySessionIssuer{
		channel:        c,
		serverAgentID:  strings.TrimSpace(serverAgentID),
		credentialKind: kind,
	}
}

func (issuer *llmProxySessionIssuer) IssueLLMProxySession(ctx context.Context, selectorSessionID string) (agent.AgentTeamLLMProxySession, error) {
	return issuer.post(ctx, "/llm-proxy-session", selectorSessionID)
}

func (issuer *llmProxySessionIssuer) RefreshLLMProxySession(ctx context.Context, selectorSessionID string) (agent.AgentTeamLLMProxySession, error) {
	return issuer.post(ctx, "/llm-proxy-session/refresh", selectorSessionID)
}

func (issuer *llmProxySessionIssuer) post(ctx context.Context, suffix string, selectorSessionID string) (agent.AgentTeamLLMProxySession, error) {
	if issuer == nil || issuer.channel == nil {
		return agent.AgentTeamLLMProxySession{}, fmt.Errorf("agentteam llm proxy session issuer is unavailable")
	}
	client := issuer.channel.APIClient(issuer.serverAgentID)
	if client == nil {
		return agent.AgentTeamLLMProxySession{}, fmt.Errorf("agentteam llm proxy session client is unavailable")
	}

	var response llmProxySessionResponse
	if err := client.Post(ctx, client.AgentRuntimePath(suffix), llmProxySessionRequest{
		SessionID:      strings.TrimSpace(selectorSessionID),
		CredentialKind: strings.TrimSpace(issuer.credentialKind),
	}, &response); err != nil {
		return agent.AgentTeamLLMProxySession{}, err
	}
	return agent.AgentTeamLLMProxySession{
		SessionID:      strings.TrimSpace(response.SessionID),
		ProxyToken:     strings.TrimSpace(response.ProxyToken),
		ExpiresAt:      response.ExpiresAt.UTC(),
		RefreshAt:      response.RefreshAt,
		MaasBaseURL:    strings.TrimSpace(response.MaasBaseURL),
		CredentialKind: strings.TrimSpace(response.CredentialKind),
	}, nil
}
