package handlers

import (
	"context"
	"encoding/json"
	"strings"
)

// PermissionHandler handles session/request_permission (spec §5.1).
//
// 行为分两层：
//   - fs.* 工具调用由服务端直接应答（不经过本 handler）。
//   - 其他工具调用：若注入了 PermissionDecider（生产路径），交由其裁决——命中
//     agent kind 白名单则自动放行，否则挂起等待人工审批；未注入 decider 时
//     （部分单测/向后兼容）回退到「默认拒绝」的纯本地逻辑。
type PermissionHandler struct {
	decider PermissionDecider
}

// PermOption 是 session/request_permission 提供的一个候选选项。
type PermOption struct {
	ID   string `json:"id"`
	Name string `json:"name,omitempty"`
}

// PermissionDecider 是权限裁决器契约。实现放在 internal/acp 主包（PermissionService），
// 以接口注入避免 handlers 子包反向 import 主包形成循环。返回选中的 option id；
// 空串表示拒绝。
type PermissionDecider interface {
	Decide(ctx context.Context, sess SessionContext, agentRequestID string,
		toolCall json.RawMessage, options []PermOption) (chosenOptionID string)
}

// NewPermissionHandler 构造 PermissionHandler。decider 可为 nil（回退到本地默认拒绝）。
func NewPermissionHandler(decider PermissionDecider) *PermissionHandler {
	return &PermissionHandler{decider: decider}
}

type permissionParams struct {
	SessionID string          `json:"sessionId"`
	ToolCall  json.RawMessage `json:"toolCall"`
	Options   []PermOption    `json:"options"`
}

type permOutcomeSelected struct {
	ID string `json:"id"`
}

type permOutcome struct {
	Selected *permOutcomeSelected `json:"selected,omitempty"`
}

type permResult struct {
	Outcome permOutcome `json:"outcome"`
}

// Handle 解析参数后委托 decider 裁决；无 decider 时回退到本地默认拒绝逻辑。
// agentRequestID 是代理侧 JSON-RPC request id，用于持久化与排障。
func (h *PermissionHandler) Handle(ctx context.Context, sess SessionContext, agentRequestID string, paramsJSON json.RawMessage) FsResult {
	var p permissionParams
	if err := json.Unmarshal(paramsJSON, &p); err != nil {
		return FsResult{Err: &FsError{Code: -32602, Message: "invalid params: " + err.Error()}}
	}

	var chosen string
	if h.decider != nil {
		chosen = h.decider.Decide(ctx, sess, agentRequestID, p.ToolCall, p.Options)
	} else {
		chosen = defaultRejectChoice(p.Options)
	}

	if chosen == "" {
		out, _ := json.Marshal(permResult{Outcome: permOutcome{}})
		return FsResult{OK: out}
	}
	out, _ := json.Marshal(permResult{Outcome: permOutcome{Selected: &permOutcomeSelected{ID: chosen}}})
	return FsResult{OK: out}
}

// defaultRejectChoice 是无 decider 时的回退：优先选 reject 类选项，否则返回空（拒绝）。
func defaultRejectChoice(options []PermOption) string {
	for _, opt := range options {
		lc := strings.ToLower(opt.ID)
		if strings.Contains(lc, "reject") || strings.Contains(lc, "deny") || strings.Contains(lc, "no") {
			return opt.ID
		}
	}
	return ""
}
