package dialectsfcrm

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

// TestFieldScaleReportsDeclaredScaleAndNeverInventsOne pins pack#4831 D6 (a
// declared scale wins, including a declared 0 — nil means "not declared", it
// does not mean zero) and the deliberate absence of a type default: until the
// substrate can carry D2's exception list, a field that declares no scale
// reports none rather than being moved to 2.
//
// The declared-zero cases are the discriminating ones for D6: the old
// `*f.Scale > 0` guard could not tell "declared as zero decimals" from "not
// declared", which is a distinction Salesforce makes (Opportunity.Probability).
func TestFieldScaleReportsDeclaredScaleAndNeverInventsOne(t *testing.T) {
	percent := models.FieldType(constants.FieldTypePercent)
	currency := models.FieldType(constants.FieldTypeCurrency)
	scale := func(v int) *int { return &v }

	for _, tc := range []struct {
		name  string
		field models.FieldMetadata
		want  int
	}{
		{
			name:  "percent without a declared scale reports none, rather than inventing 2",
			field: models.FieldMetadata{APIName: "Discount__c", Type: constants.FieldTypePercent},
			want:  0,
		},
		{
			name: "currency without a declared scale reports none",
			// Salesforce reports scale 0 for Account.AnnualRevenue, Campaign.ActualCost,
			// Campaign.BudgetedCost and Campaign.ExpectedRevenue among others, so a
			// currency default of 2 would be wrong for them and could not be excepted
			// until the substrate exists. See #4831 D2.
			field: models.FieldMetadata{APIName: "Amount__c", Type: constants.FieldTypeCurrency},
			want:  0,
		},
		{
			name:  "plain number without declared scale stays at zero",
			field: models.FieldMetadata{APIName: "Seats__c", Type: constants.FieldTypeDouble},
			want:  0,
		},
		{
			name:  "declared zero on a percent field is honoured",
			field: models.FieldMetadata{APIName: "Probability", Type: constants.FieldTypePercent, Scale: scale(0)},
			want:  0,
		},
		{
			name:  "a percent field that declares 2 reports 2 — the case this PR actually changes",
			field: models.FieldMetadata{APIName: "Discount__c", Type: constants.FieldTypePercent, Scale: scale(2)},
			want:  2,
		},
		{
			name:  "declared scale on a currency field is honoured",
			field: models.FieldMetadata{APIName: "Rollup__c", Type: constants.FieldTypeCurrency, Scale: scale(2)},
			want:  2,
		},
		{
			name:  "declared non-default scale wins over the type default",
			field: models.FieldMetadata{APIName: "Exchange_Rate__c", Type: constants.FieldTypeDouble, Scale: scale(4)},
			want:  4,
		},
		{
			name: "formula returning percent resolves through the computed-type reader",
			field: models.FieldMetadata{
				APIName:    "Average_Discount__c",
				Type:       constants.FieldTypeFormula,
				ReturnType: &percent,
				Scale:      scale(2),
			},
			want: 2,
		},
		{
			name: "rollup over a currency source keeps its resolver-declared scale",
			field: models.FieldMetadata{
				APIName:    "Net_Fees__c",
				Type:       constants.FieldTypeRollupSummary,
				ReturnType: &currency,
				Scale:      scale(2),
			},
			want: 2,
		},
		{
			name:  "a negative declared scale is not a declaration",
			field: models.FieldMetadata{APIName: "Broken__c", Type: constants.FieldTypePercent, Scale: scale(-1)},
			want:  0,
		},
		{
			name:  "a declared scale beyond Salesforce's maximum is bounded, so describe and display agree",
			field: models.FieldMetadata{APIName: "Absurd__c", Type: constants.FieldTypePercent, Scale: scale(1000000)},
			want:  18,
		},
		{
			name:  "non-numeric types report no scale",
			field: models.FieldMetadata{APIName: "Name", Type: constants.FieldTypeString},
			want:  0,
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			if got := fieldScale(tc.field); got != tc.want {
				t.Fatalf("fieldScale(%s) = %d, want %d", tc.field.APIName, got, tc.want)
			}
		})
	}
}
