package aifin

import (
	"testing"

	"github.com/stretchr/testify/require"
)

func TestDefinitionPinsClosedAIFinCatalog(t *testing.T) {
	t.Parallel()

	definition := Definition()
	require.Equal(t, Domain, definition.Domain)
	require.Equal(t, 1, definition.Version)
	require.Equal(t, "Wind AIFin Market", definition.Name)

	wantNames := []string{
		ActionGetStockPriceIndicators,
		ActionGetStockKline,
		ActionSearchStocks,
		ActionGetStockFundamentals,
		ActionGetFundPriceIndicators,
		ActionGetFundKline,
		ActionSearchFunds,
		ActionGetFundPerformance,
		ActionGetIndexPriceIndicators,
		ActionGetIndexKline,
		ActionGetCompanyAnnouncements,
		ActionGetFinancialNews,
		ActionNaturalLanguageGetEDBData,
	}
	gotNames := make([]string, 0, len(definition.Actions))
	for _, action := range definition.Actions {
		gotNames = append(gotNames, action.Name)
		require.NotEqual(t, "list-tools", action.Name)
		require.NotEqual(t, "call-tool", action.Name)
		require.Equal(t, "read", action.Safety.Class)
		require.True(t, action.Safety.Idempotent)
		require.False(t, action.Safety.Destructive)
		require.Equal(t, schemaDialect, action.InputSchema["$schema"])
		require.Equal(t, map[string]any{
			"$schema":              schemaDialect,
			"type":                 "object",
			"description":          "The normalized result returned by the Wind MCP tool.",
			"additionalProperties": false,
			"properties": map[string]any{
				"result": map[string]any{
					"description": "The JSON value returned by the named Wind MCP tool.",
				},
			},
			"required": []any{"result"},
		}, action.OutputSchema)
	}
	require.Equal(t, wantNames, gotNames)
}

func TestDefinitionPinsExactInputContractFamilies(t *testing.T) {
	t.Parallel()

	actions := make(map[string]map[string]any)
	for _, action := range Definition().Actions {
		actions[action.Name] = action.InputSchema
	}

	price := actions[ActionGetStockPriceIndicators]
	require.Equal(t, []any{"windcode"}, price["required"])
	priceProperties := price["properties"].(map[string]any)
	require.Equal(t, 2_000, priceProperties["windcode"].(map[string]any)["maxLength"])
	require.Equal(t, "\\S", priceProperties["windcode"].(map[string]any)["pattern"])
	require.Equal(t, 4_000, priceProperties["indexes"].(map[string]any)["maxLength"])

	kline := actions[ActionGetFundKline]
	require.Equal(t, []any{"windcode", "begin_date", "end_date"}, kline["required"])
	klineProperties := kline["properties"].(map[string]any)
	require.Equal(t, "date", klineProperties["begin_date"].(map[string]any)["format"])
	require.Equal(t, []any{
		"1min", "5min", "10min", "15min", "30min", "60min",
		"120min", "240min", "1d", "1w", "1mo", "1y", "1q", "6mo",
	}, klineProperties["period"].(map[string]any)["enum"])
	require.Equal(t, []any{"0", "1"}, klineProperties["aftype"].(map[string]any)["enum"])
	require.Equal(t, []any{"0", "1"}, klineProperties["issusp"].(map[string]any)["enum"])

	question := actions[ActionSearchStocks]
	require.Equal(t, []any{"question"}, question["required"])
	questionProperties := question["properties"].(map[string]any)
	require.Equal(t, 4_000, questionProperties["question"].(map[string]any)["maxLength"])

	documents := actions[ActionGetFinancialNews]
	require.Equal(t, []any{"query"}, documents["required"])
	documentProperties := documents["properties"].(map[string]any)
	require.Equal(t, 1, documentProperties["top_k"].(map[string]any)["minimum"])
	require.Equal(t, 100, documentProperties["top_k"].(map[string]any)["maximum"])

	economic := actions[ActionNaturalLanguageGetEDBData]
	require.Equal(t, []any{"executionMode", "question"}, economic["required"])
	economicProperties := economic["properties"].(map[string]any)
	require.Equal(t, []any{
		"search", "fetch", "searchFetch", "仅搜索", "仅提数", "搜索并提数",
	}, economicProperties["executionMode"].(map[string]any)["enum"])
	require.Equal(t, "^(all|[0-9]+)$", economicProperties["observation"].(map[string]any)["pattern"])
	require.Equal(t, 6, economicProperties["observation"].(map[string]any)["maxLength"])
}
