package models

import (
	"crypto/md5"
	"encoding/hex"
	"strconv"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/constants"
	"gorm.io/gorm"
)

func TestMonthlyProportion_BuildID(t *testing.T) {
	// Create a MonthlyProportion instance with test data.
	mp := MonthlyProportion{
		Timestamp:     1678886400, // Example timestamp
		Region:        "us-east-1",
		CloudService:  constants.ElasticCompute,
		Env:           constants.Prod,
		MeteringGroup: constants.Serverless,
		Tenant:        "test-tenant-123",
	}

	// Manually build the expected ID string.
	strs := []string{
		strconv.Itoa(int(mp.Timestamp)),
		mp.Region,
		string(mp.CloudService),
		string(mp.Env),
		string(mp.MeteringGroup),
		mp.Tenant,
	}
	text := strings.Join(strs, "-")
	hash := md5.Sum([]byte(text))
	expectedID := hex.EncodeToString(hash[:])

	// Call the BuildID method and assert the ID is as expected.
	actualID := mp.BuildID()
	assert.Equal(t, expectedID, actualID, "BuildID should generate the correct MD5 hash")
	assert.Equal(t, expectedID, mp.ID, "BuildID should set the ID field of the struct")
}

func TestMonthlyProportion_BeforeCreate(t *testing.T) {
	// Create a MonthlyProportion instance with an empty ID.
	mp := MonthlyProportion{
		Timestamp:     1678886400,
		Region:        "us-east-1",
		CloudService:  constants.ElasticCompute,
		Env:           constants.Prod,
		MeteringGroup: constants.Serverless,
		Tenant:        "test-tenant-123",
	}
	mp.ID = "" // Ensure ID is empty for BeforeCreate to generate it

	// Call BeforeCreate. Since we don't have a real DB context, we pass nil.
	// The primary logic we're testing here is the ID generation.
	err := mp.BeforeCreate(&gorm.DB{})
	assert.NoError(t, err, "BeforeCreate should not return an error")
	assert.NotEmpty(t, mp.ID, "BeforeCreate should generate an ID if it's empty")

	// Test case where ID is already set.
	originalID := "existing-id-123"
	mpWithID := MonthlyProportion{
		ID:            originalID,
		Timestamp:     1678886400,
		Region:        "us-east-1",
		CloudService:  constants.ElasticCompute,
		Env:           constants.Prod,
		MeteringGroup: constants.Serverless,
		Tenant:        "test-tenant-123",
	}
	err = mpWithID.BeforeCreate(&gorm.DB{})
	assert.NoError(t, err, "BeforeCreate should not return an error when ID is already set")
	assert.Equal(t, originalID, mpWithID.ID, "BeforeCreate should not change the ID if it's already set")
}
