package qichacha

// Input and output JSON Schema builders for the Qichacha catalog, ported
// from the upstream OpenConnector actions. Record fields are nullable
// strings because Qichacha emits them sparse.

const schemaDialect = "https://json-schema.org/draft/2020-12/schema"

func objectSchema(properties map[string]any, required []string) map[string]any {
	schema := map[string]any{
		"$schema":              schemaDialect,
		"type":                 "object",
		"additionalProperties": false,
		"properties":           properties,
	}
	if len(required) > 0 {
		anyRequired := make([]any, 0, len(required))
		for _, name := range required {
			anyRequired = append(anyRequired, name)
		}
		schema["required"] = anyRequired
	}
	return schema
}

func nullableStringSchema(description string) map[string]any {
	return map[string]any{
		"anyOf": []any{
			map[string]any{"type": "null"},
			map[string]any{"type": "string"},
		},
		"description": description,
	}
}

func nullableIntegerSchema(description string, minimum, maximum int) map[string]any {
	return map[string]any{
		"anyOf": []any{
			map[string]any{"type": "null"},
			map[string]any{"type": "integer", "minimum": minimum, "maximum": maximum},
		},
		"description": description,
	}
}

var (
	searchKeySchema = map[string]any{
		"type":        "string",
		"pattern":     `\S`,
		"description": "The exact company name or unified social credit code to query.",
	}
	pageIndexSchema = map[string]any{
		"type":        "integer",
		"minimum":     1,
		"description": "The one-based page number. Defaults to 1.",
	}
	pageSizeSchema = map[string]any{
		"type":        "integer",
		"minimum":     1,
		"maximum":     20,
		"description": "The number of records per page. Defaults to 10 and cannot exceed 20.",
	}
)

// searchInputSchema is the shared lookup-and-pagination request.
func searchInputSchema() map[string]any {
	return objectSchema(map[string]any{
		"searchKey": searchKeySchema,
		"pageIndex": pageIndexSchema,
		"pageSize":  pageSizeSchema,
	}, []string{"searchKey"})
}

// paginationProperties echo the Qichacha paging envelope.
func paginationProperties() map[string]any {
	return map[string]any{
		"pageIndex":    map[string]any{"type": "integer", "minimum": 1, "description": "The one-based page number returned by Qichacha."},
		"pageSize":     map[string]any{"type": "integer", "minimum": 1, "description": "The page size returned by Qichacha."},
		"totalRecords": map[string]any{"type": "integer", "minimum": 0, "description": "The total number of matching records."},
		"verifyResult": nullableIntegerSchema("Whether Qichacha found data for the company: 1 for found or 0 for not found.", 0, 1),
		"orderNumber":  nullableStringSchema("The Qichacha request order number."),
	}
}

// shareholderSchema describes one registered shareholder record.
func shareholderSchema() map[string]any {
	return map[string]any{
		"$schema":              schemaDialect,
		"type":                 "object",
		"description":          "A registered Qichacha shareholder record.",
		"additionalProperties": false,
		"properties": map[string]any{
			"keyNo":                     nullableStringSchema("The Qichacha shareholder identifier."),
			"name":                      nullableStringSchema("The shareholder or investor name."),
			"type":                      nullableStringSchema("The shareholder or investor type."),
			"stockPercent":              nullableStringSchema("The registered ownership percentage."),
			"subscribedAmount":          nullableStringSchema("The formatted subscribed capital amount."),
			"subscribedCapital":         nullableStringSchema("The numeric portion of the subscribed capital amount."),
			"subscribedCapitalUnit":     nullableStringSchema("The unit of the subscribed capital amount."),
			"subscribedCapitalCurrency": nullableStringSchema("The currency code of the subscribed capital amount."),
			"subscribedDate":            nullableStringSchema("The subscribed capital date."),
			"stakeDate":                 nullableStringSchema("The first registered ownership date."),
			"creditCode":                nullableStringSchema("The shareholder's unified social credit code."),
			"area":                      nullableStringSchema("The shareholder's nationality, region, or registration area."),
			"subscriptions": map[string]any{
				"type":        "array",
				"description": "The shareholder's individual subscribed contribution records.",
				"items": map[string]any{
					"$schema":              schemaDialect,
					"type":                 "object",
					"description":          "One subscribed contribution record.",
					"additionalProperties": false,
					"properties": map[string]any{
						"contributionType": nullableStringSchema("The contribution method."),
						"capital":          nullableStringSchema("The subscribed capital amount in the parent record's unit."),
						"date":             nullableStringSchema("The subscribed contribution date."),
					},
				},
			},
		},
	}
}

// historicalInvestmentSchema describes one historical investment record.
func historicalInvestmentSchema() map[string]any {
	return map[string]any{
		"$schema":              schemaDialect,
		"type":                 "object",
		"description":          "A historical Qichacha investment record.",
		"additionalProperties": false,
		"properties": map[string]any{
			"keyNo":                     nullableStringSchema("The Qichacha identifier of the invested company."),
			"companyName":               nullableStringSchema("The invested company name."),
			"legalRepresentative":       legalRepresentativeSchema(),
			"registeredCapital":         nullableStringSchema("The formatted registered capital."),
			"registeredCapitalValue":    nullableStringSchema("The numeric portion of the registered capital."),
			"registeredCapitalUnit":     nullableStringSchema("The registered capital unit."),
			"registeredCapitalCurrency": nullableStringSchema("The registered capital currency code."),
			"fundedRatio":               nullableStringSchema("The historical ownership percentage."),
			"status":                    nullableStringSchema("The invested company's registration status."),
			"startDate":                 nullableStringSchema("The invested company's establishment date."),
			"subscribedAmount":          nullableStringSchema("The formatted subscribed investment amount."),
			"subscribedCapital":         nullableStringSchema("The numeric portion of the subscribed investment amount."),
			"subscribedCapitalUnit":     nullableStringSchema("The subscribed investment amount unit."),
			"subscribedCapitalCurrency": nullableStringSchema("The subscribed investment currency code."),
			"exitDate":                  nullableStringSchema("The date on which the investment ended."),
		},
	}
}

func legalRepresentativeSchema() map[string]any {
	return map[string]any{
		"anyOf": []any{
			map[string]any{"type": "null"},
			map[string]any{
				"$schema":              schemaDialect,
				"type":                 "object",
				"description":          "The invested company's legal representative.",
				"additionalProperties": false,
				"properties": map[string]any{
					"keyNo": nullableStringSchema("The Qichacha person identifier."),
					"name":  nullableStringSchema("The legal representative name."),
				},
			},
		},
		"description": "The invested company's legal representative.",
	}
}
