package server

import (
	"context"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api/billing"
	"github.com/tidbcloud/AgentTeam/internal/maas/availability"
)

const (
	newUserTrialCreditAmountAgentTeamCredits int64 = 300
	newUserTrialCreditSource                  = "new_user_trial"
	newUserTrialCreditReason                  = "default-workspace-bootstrap"
	newUserTrialCreditOperator                = "agentteam-server"
	defaultWorkspaceHostedModelID             = "deepseek_v4_flash"
)

type defaultWorkspaceBillingProvisioner struct {
	hosted *availability.Client
	credit interface {
		GrantHostedCredit(context.Context, billing.HostedCreditGrantParams) (billing.HostedCreditGrant, error)
	}
}

func (provisioner defaultWorkspaceBillingProvisioner) EnsureDefaultWorkspacePostCommit(ctx context.Context, organizationID string, userID string) error {
	trimmedOrganizationID := strings.TrimSpace(organizationID)
	trimmedUserID := strings.TrimSpace(userID)
	if trimmedOrganizationID == "" || trimmedUserID == "" {
		return fmt.Errorf("default workspace billing identity is incomplete")
	}
	if provisioner.hosted == nil {
		return fmt.Errorf("agentteam-maas hosted entitlement client is not configured")
	}
	if provisioner.credit == nil {
		return fmt.Errorf("agentteam-maas billing client is not configured")
	}
	grantID := availability.HostedEntitlementGrantID(trimmedOrganizationID, "hosted_model_id", defaultWorkspaceHostedModelID)
	if _, err := provisioner.hosted.UpsertHostedEntitlementGrant(ctx, grantID, availability.EntitlementGrantRequest{
		OrganizationID: trimmedOrganizationID,
		HostedModelID:  defaultWorkspaceHostedModelID,
		GrantSource:    newUserTrialCreditSource,
		Status:         "active",
	}); err != nil {
		return fmt.Errorf("ensure new-user hosted entitlement: %w", err)
	}
	_, err := provisioner.credit.GrantHostedCredit(ctx, billing.HostedCreditGrantParams{
		OrganizationID:   trimmedOrganizationID,
		IdempotencyKey:   newUserTrialCreditIdempotencyKey(trimmedUserID, trimmedOrganizationID),
		CreditUnit:       "agentteam_credit",
		CreditAmount:     newUserTrialCreditAmountAgentTeamCredits,
		GrantSourceType:  newUserTrialCreditSource,
		GrantReasonRef:   newUserTrialCreditReason,
		Refundable:       false,
		OperatorIdentity: newUserTrialCreditOperator,
		SourceRef:        "user:" + trimmedUserID,
	})
	if err != nil {
		return fmt.Errorf("grant new-user trial credit: %w", err)
	}
	return nil
}

func newUserTrialCreditIdempotencyKey(userID string, organizationID string) string {
	return fmt.Sprintf("new-user-trial-credit:v1:%s:%s", strings.TrimSpace(userID), strings.TrimSpace(organizationID))
}
