package access

import (
	"context"
	"strings"

	"sub2api-cn-relay-manager/internal/host/sub2api"
)

func SuspectsOpenAIResponsesCapabilityMismatch(probe sub2api.ProbeResult) bool {
	if probe.OK {
		return false
	}
	message := strings.ToLower(strings.TrimSpace(probe.Message))
	if message == "" {
		return false
	}
	if strings.Contains(message, "api returned 403: forbidden") {
		return true
	}
	return strings.Contains(message, "responses api") &&
		(strings.Contains(message, "当前测试接口仅支持") ||
			strings.Contains(message, "账号本身可正常使用") ||
			strings.Contains(message, "please directly") ||
			strings.Contains(message, "actual api"))
}

func ShouldAttemptOpenAIResponsesCapabilityRepair(suspect bool, completion sub2api.GatewayCompletionResult) bool {
	if !suspect || completion.OK {
		return false
	}
	if completion.StatusCode != 502 && completion.StatusCode != 503 {
		return false
	}
	body := strings.ToLower(strings.TrimSpace(completion.BodyPreview))
	return strings.Contains(body, "service temporarily unavailable") ||
		strings.Contains(body, "no available accounts")
}

func (s *Service) maybeRepairOpenAIResponsesCapability(ctx context.Context, req ClosureRequest, completionReq sub2api.GatewayCompletionCheckRequest, completion sub2api.GatewayCompletionResult) (sub2api.GatewayCompletionResult, error) {
	if !ShouldAttemptOpenAIResponsesCapabilityRepair(req.ResponsesCapabilitySuspect, completion) {
		return completion, nil
	}
	accountIDs := normalizedAccountIDs(req.AccountIDs)
	if len(accountIDs) == 0 {
		return completion, nil
	}
	if err := RepairOpenAIResponsesCapability(ctx, s.host, accountIDs); err != nil {
		return completion, nil
	}
	return s.checkGatewayCompletionWithRetry(ctx, completionReq)
}

func RepairOpenAIResponsesCapability(ctx context.Context, host Host, accountIDs []string) error {
	if host == nil {
		return nil
	}
	normalized := normalizedAccountIDs(accountIDs)
	if len(normalized) == 0 {
		return nil
	}
	if err := host.DisableOpenAIResponsesAPI(ctx, normalized); err != nil {
		return err
	}
	if err := host.ClearTempUnschedulable(ctx, normalized); err != nil {
		return nil
	}
	return nil
}

func normalizedAccountIDs(accountIDs []string) []string {
	seen := map[string]struct{}{}
	values := make([]string, 0, len(accountIDs))
	for _, rawID := range accountIDs {
		accountID := strings.TrimSpace(rawID)
		if accountID == "" {
			continue
		}
		if _, ok := seen[accountID]; ok {
			continue
		}
		seen[accountID] = struct{}{}
		values = append(values, accountID)
	}
	return values
}
