package oci

import (
	"context"
	"fmt"

	"github.com/oracle/oci-go-sdk/v65/common"
	"github.com/oracle/oci-go-sdk/v65/generativeaiinference"
)

// RerankRank 是重排结果的一项:index 指向入参 documents 下标。
type RerankRank struct {
	Index int
	Score float64
}

// GuardrailCategory 是内容审核分类得分(OVERALL / BLOCKLIST)。
type GuardrailCategory struct {
	Name  string
	Score float64
}

// GuardrailPiiHit 是一处 PII 命中(片段原文与位置)。
type GuardrailPiiHit struct {
	Text   string
	Label  string
	Score  float64
	Offset int
	Length int
}

// GuardrailsOutcome 汇总 ApplyGuardrails 三能力结果。
type GuardrailsOutcome struct {
	Categories           []GuardrailCategory
	Pii                  []GuardrailPiiHit
	PromptInjectionScore *float64
}

// GenAiRerank 实现 Client:文档重排(on-demand serving),返回按相关度排序的下标与得分。
func (c *RealClient) GenAiRerank(ctx context.Context, cred Credentials, region, modelOcid, query string, documents []string, topN *int) ([]RerankRank, error) {
	ic, err := c.genAiInferenceClient(cred, region)
	if err != nil {
		return nil, err
	}
	resp, err := ic.RerankText(ctx, generativeaiinference.RerankTextRequest{
		RerankTextDetails: generativeaiinference.RerankTextDetails{
			CompartmentId: &cred.TenancyOCID,
			ServingMode:   generativeaiinference.OnDemandServingMode{ModelId: &modelOcid},
			Input:         &query,
			Documents:     documents,
			TopN:          topN,
		},
	})
	if err != nil {
		return nil, fmt.Errorf("genai rerank: %w", err)
	}
	ranks := make([]RerankRank, 0, len(resp.DocumentRanks))
	for _, r := range resp.DocumentRanks {
		if r.Index == nil || r.RelevanceScore == nil {
			continue
		}
		ranks = append(ranks, RerankRank{Index: *r.Index, Score: *r.RelevanceScore})
	}
	return ranks, nil
}

// GenAiApplyGuardrails 实现 Client:对单条文本执行内容审核 / PII / 提示注入三检测。
func (c *RealClient) GenAiApplyGuardrails(ctx context.Context, cred Credentials, region, text string) (*GuardrailsOutcome, error) {
	ic, err := c.genAiInferenceClient(cred, region)
	if err != nil {
		return nil, err
	}
	resp, err := ic.ApplyGuardrails(ctx, generativeaiinference.ApplyGuardrailsRequest{
		ApplyGuardrailsDetails: generativeaiinference.ApplyGuardrailsDetails{
			CompartmentId: &cred.TenancyOCID,
			Input:         generativeaiinference.GuardrailsTextInput{Content: common.String(text)},
			GuardrailConfigs: &generativeaiinference.GuardrailConfigs{
				ContentModerationConfig:                 &generativeaiinference.ContentModerationConfiguration{Categories: []string{"OVERALL"}},
				PersonallyIdentifiableInformationConfig: &generativeaiinference.PersonallyIdentifiableInformationConfiguration{Types: []string{}},
				PromptInjectionConfig:                   &generativeaiinference.PromptInjectionConfiguration{},
			},
		},
	})
	if err != nil {
		return nil, fmt.Errorf("genai guardrails: %w", err)
	}
	return guardrailsOutcome(resp.Results), nil
}

// guardrailsOutcome 把 SDK 结果换算为 IR;空段置空切片,得分缺失跳过。
func guardrailsOutcome(r *generativeaiinference.GuardrailsResults) *GuardrailsOutcome {
	out := &GuardrailsOutcome{}
	if r == nil {
		return out
	}
	if r.ContentModeration != nil {
		for _, cat := range r.ContentModeration.Categories {
			if cat.Name == nil || cat.Score == nil {
				continue
			}
			out.Categories = append(out.Categories, GuardrailCategory{Name: *cat.Name, Score: *cat.Score})
		}
	}
	for _, hit := range r.PersonallyIdentifiableInformation {
		h := GuardrailPiiHit{}
		if hit.Text != nil {
			h.Text = *hit.Text
		}
		if hit.Label != nil {
			h.Label = *hit.Label
		}
		if hit.Score != nil {
			h.Score = *hit.Score
		}
		if hit.Offset != nil {
			h.Offset = *hit.Offset
		}
		if hit.Length != nil {
			h.Length = *hit.Length
		}
		out.Pii = append(out.Pii, h)
	}
	if r.PromptInjection != nil && r.PromptInjection.Score != nil {
		out.PromptInjectionScore = r.PromptInjection.Score
	}
	return out
}
