package ussd

import (
	"context"
	"encoding/json"
	"os"
	"path/filepath"
	"testing"

	"git.defalsify.org/vise.git/resource"
	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
	"git.grassecon.net/urdt/ussd/internal/models"
	"git.grassecon.net/urdt/ussd/internal/utils"
	"github.com/alecthomas/assert/v2"
	"github.com/stretchr/testify/mock"
)

// MockAccountService implements AccountServiceInterface for testing
type MockAccountService struct {
	mock.Mock
}

func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
	args := m.Called()
	return args.Get(0).(*models.AccountResponse), args.Error(1)
}

func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
	args := m.Called(publicKey)
	return args.String(0), args.Error(1)
}

func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
	args := m.Called(trackingId)
	return args.String(0), args.Error(1)
}

func TestCreateAccount(t *testing.T) {
	// Setup
	tempDir, err := os.MkdirTemp("", "test_create_account")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(tempDir) // Clean up after the test run

	sessionID := "07xxxxxxxx"

	// Set up the data file path using the session ID
	accountFilePath := filepath.Join(tempDir, sessionID+"_data")

	// Initialize account file handler
	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)

	// Create a mock account service
	mockAccountService := &MockAccountService{}
	mockAccountResponse := &models.AccountResponse{
		Ok: true,
		Result: struct {
			CustodialId json.Number `json:"custodialId"`
			PublicKey   string      `json:"publicKey"`
			TrackingId  string      `json:"trackingId"`
		}{
			CustodialId: "test-custodial-id",
			PublicKey:   "test-public-key",
			TrackingId:  "test-tracking-id",
		},
	}

	// Set up expectations for the mock account service
	mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)

	// Initialize Handlers with mock account service
	h := &Handlers{
		fs:                 &FSData{Path: accountFilePath},
		accountFileHandler: accountFileHandler,
		accountService:     mockAccountService,
	}

	tests := []struct {
		name           string
		existingData   map[string]string
		expectedResult resource.Result
		expectedData   map[string]string
	}{
		{
			name:         "New account creation",
			existingData: nil,
			expectedResult: resource.Result{
				FlagSet: []uint32{models.USERFLAG_ACCOUNT_CREATED},
			},
			expectedData: map[string]string{
				"TrackingId":  "test-tracking-id",
				"PublicKey":   "test-public-key",
				"CustodialId": "test-custodial-id",
				"Status":      "PENDING",
				"Gender":      "Not provided",
				"YOB":         "Not provided",
				"Location":    "Not provided",
				"Offerings":   "Not provided",
				"FirstName":   "Not provided",
				"FamilyName":  "Not provided",
			},
		},
		{
			name: "Existing account",
			existingData: map[string]string{
				"TrackingId":  "test-tracking-id",
				"PublicKey":   "test-public-key",
				"CustodialId": "test-custodial-id",
				"Status":      "PENDING",
				"Gender":      "Not provided",
				"YOB":         "Not provided",
				"Location":    "Not provided",
				"Offerings":   "Not provided",
				"FirstName":   "Not provided",
				"FamilyName":  "Not provided",
			},
			expectedResult: resource.Result{},
			expectedData: map[string]string{
				"TrackingId":  "test-tracking-id",
				"PublicKey":   "test-public-key",
				"CustodialId": "test-custodial-id",
				"Status":      "PENDING",
				"Gender":      "Not provided",
				"YOB":         "Not provided",
				"Location":    "Not provided",
				"Offerings":   "Not provided",
				"FirstName":   "Not provided",
				"FamilyName":  "Not provided",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the data file path using the session ID
			accountFilePath := filepath.Join(tempDir, sessionID+"_data")

			// Setup existing data if any
			if tt.existingData != nil {
				data, _ := json.Marshal(tt.existingData)
				err := os.WriteFile(accountFilePath, data, 0644)
				if err != nil {
					t.Fatalf("Failed to write existing data: %v", err)
				}
			}

			// Call the function
			result, err := h.CreateAccount(context.Background(), "", nil)

			// Check for errors
			if err != nil {
				t.Fatalf("CreateAccount returned an error: %v", err)
			}

			// Check the result
			if len(result.FlagSet) != len(tt.expectedResult.FlagSet) {
				t.Errorf("Expected %d flags, got %d", len(tt.expectedResult.FlagSet), len(result.FlagSet))
			}
			for i, flag := range tt.expectedResult.FlagSet {
				if result.FlagSet[i] != flag {
					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
				}
			}

			// Check the stored data
			data, err := os.ReadFile(accountFilePath)
			if err != nil {
				t.Fatalf("Failed to read account data file: %v", err)
			}

			var storedData map[string]string
			err = json.Unmarshal(data, &storedData)
			if err != nil {
				t.Fatalf("Failed to unmarshal stored data: %v", err)
			}

			for key, expectedValue := range tt.expectedData {
				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
				}
			}
		})
	}
}

func TestCreateAccount_Success(t *testing.T) {
	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
	mockCreateAccountService := new(mocks.MockAccountService)

	mockAccountFileHandler.On("EnsureFileExists").Return(nil)

	// Mock that no account data exists
	mockAccountFileHandler.On("ReadAccountData").Return(nil, nil)

	// Define expected account response after api call
	expectedAccountResp := &models.AccountResponse{
		Ok: true,
		Result: struct {
			CustodialId json.Number `json:"custodialId"`
			PublicKey   string      `json:"publicKey"`
			TrackingId  string      `json:"trackingId"`
		}{
			CustodialId: "12",
			PublicKey:   "0x8E0XSCSVA",
			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
		},
	}
	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)

	// Mock WriteAccountData to not error
	mockAccountFileHandler.On("WriteAccountData", mock.Anything).Return(nil)

	handlers := &Handlers{
		accountService: mockCreateAccountService,
	}

	actualResponse, err := handlers.accountService.CreateAccount()

	// Assert results
	assert.NoError(t, err)
	assert.Equal(t, expectedAccountResp.Ok, true)
	assert.Equal(t, expectedAccountResp, actualResponse)
}

func TestSavePin(t *testing.T) {
	// Setup
	tempDir, err := os.MkdirTemp("", "test_save_pin")
	if err != nil {
		t.Fatalf("Failed to create temp directory: %v", err)
	}
	defer os.RemoveAll(tempDir)

	sessionID := "07xxxxxxxx"

	// Set up the data file path using the session ID
	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
	initialAccountData := map[string]string{
		"TrackingId": "test-tracking-id",
		"PublicKey":  "test-public-key",
	}
	data, _ := json.Marshal(initialAccountData)
	err = os.WriteFile(accountFilePath, data, 0644)
	if err != nil {
		t.Fatalf("Failed to write initial account data: %v", err)
	}

	// Create a new AccountFileHandler and set it in the Handlers struct
	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
	h := &Handlers{
		accountFileHandler: accountFileHandler,
	}

	tests := []struct {
		name           string
		input          []byte
		expectedFlags  []uint32
		expectedData   map[string]string
		expectedErrors bool
	}{
		{
			name:          "Valid PIN",
			input:         []byte("1234"),
			expectedFlags: []uint32{},
			expectedData: map[string]string{
				"TrackingId": "test-tracking-id",
				"PublicKey":  "test-public-key",
				"AccountPIN": "1234",
			},
		},
		{
			name:           "Invalid PIN - non-numeric",
			input:          []byte("12ab"),
			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN},
			expectedData:   initialAccountData, // No changes expected
			expectedErrors: false,
		},
		{
			name:           "Invalid PIN - less than 4 digits",
			input:          []byte("123"),
			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN},
			expectedData:   initialAccountData, // No changes expected
			expectedErrors: false,
		},
		{
			name:           "Invalid PIN - more than 4 digits",
			input:          []byte("12345"),
			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN},
			expectedData:   initialAccountData, // No changes expected
			expectedErrors: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Ensure the file exists before running the test
			err := accountFileHandler.EnsureFileExists()
			if err != nil {
				t.Fatalf("Failed to ensure account file exists: %v", err)
			}

			result, err := h.SavePin(context.Background(), "", tt.input)
			if err != nil && !tt.expectedErrors {
				t.Fatalf("SavePin returned an unexpected error: %v", err)
			}

			if len(result.FlagSet) != len(tt.expectedFlags) {
				t.Errorf("Expected %d flags, got %d", len(tt.expectedFlags), len(result.FlagSet))
			}
			for i, flag := range tt.expectedFlags {
				if result.FlagSet[i] != flag {
					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
				}
			}

			data, err := os.ReadFile(accountFilePath)
			if err != nil {
				t.Fatalf("Failed to read account data file: %v", err)
			}

			var storedData map[string]string
			err = json.Unmarshal(data, &storedData)
			if err != nil {
				t.Fatalf("Failed to unmarshal stored data: %v", err)
			}

			for key, expectedValue := range tt.expectedData {
				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
				}
			}
		})
	}
}

func TestSaveLocation(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
	}{
		{
			name:           "Successful Save",
			input:          []byte("Mombasa"),
			existingData:   map[string]string{"Location": "Mombasa"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
		{
			name:           "Empty location input",
			input:          []byte{},
			existingData:   map[string]string{"OtherKey": "OtherValue"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["Location"] == string(tt.input)
				})).Return(tt.writeError)
			} else if len(tt.input) == 0 {
				// For empty input, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
				return
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call Save Location
			result, err := h.SaveLocation(context.Background(), "save_location", tt.input)

			if err != nil {
				t.Fatalf("Failed to save location with error: %v", err)
			}

			savedData, err := h.accountFileHandler.ReadAccountData()
			if err == nil {
				//Assert that the input provided is what was saved into the file
				assert.Equal(t, string(tt.input), savedData["Location"])
			}

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}

func TestSaveFirstname(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
	}{
		{
			name:           "Successful Save",
			input:          []byte("Joe"),
			existingData:   map[string]string{"Name": "Joe"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
		{
			name:          "Empty Input",
			input:         []byte{},
			existingData:  map[string]string{"OtherKey": "OtherValue"},
			writeError:    nil,
			expectedError: nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["FirstName"] == string(tt.input)
				})).Return(tt.writeError)
			} else if len(tt.input) == 0 {
				// For empty input, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
				return
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call save location
			result, err := h.SaveFirstname(context.Background(), "save_location", tt.input)

			if err != nil {
				t.Fatalf("Failed to save first name with error: %v", err)
			}
			savedData, err := h.accountFileHandler.ReadAccountData()
			if err == nil {
				//Assert that the input provided is what was saved into the file
				assert.Equal(t, string(tt.input), savedData["FirstName"])
			}

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}

func TestSaveFamilyName(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
	}{
		{
			name:           "Successful Save",
			input:          []byte("Doe"),
			existingData:   map[string]string{"FamilyName": "Doe"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
		{
			name:          "Empty Input",
			input:         []byte{},
			existingData:  map[string]string{"FamilyName": "Doe"},
			writeError:    nil,
			expectedError: nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["FamilyName"] == string(tt.input)
				})).Return(tt.writeError)
			} else if len(tt.input) == 0 {
				// For empty input, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
				return
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call save familyname
			result, err := h.SaveFamilyname(context.Background(), "save_familyname", tt.input)

			if err != nil {
				t.Fatalf("Failed to save family name with error: %v", err)
			}
			savedData, err := h.accountFileHandler.ReadAccountData()
			if err == nil {
				//Assert that the input provided is what was saved into the file
				assert.Equal(t, string(tt.input), savedData["FamilyName"])
			}

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}

func TestSaveYOB(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
	}{
		{
			name:           "Successful Save",
			input:          []byte("2006"),
			existingData:   map[string]string{"": ""},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
		{
			name:          "YOB less than 4 digits(invalid date entry)",
			input:         []byte{},
			existingData:  map[string]string{"": ""},
			writeError:    nil,
			expectedError: nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["YOB"] == string(tt.input)
				})).Return(tt.writeError)
			} else if len(tt.input) != 4 {
				// For input whose input is not a valid yob, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
				return
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call save yob
			result, err := h.SaveYob(context.Background(), "save_yob", tt.input)

			if err != nil {
				t.Fatalf("Failed to save family name with error: %v", err)
			}
			savedData, err := h.accountFileHandler.ReadAccountData()
			if err == nil {
				//Assert that the input provided is what was saved into the file
				assert.Equal(t, string(tt.input), savedData["YOB"])
			}

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}

func TestSaveOfferings(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
	}{
		{
			name:           "Successful Save",
			input:          []byte("Bananas"),
			existingData:   map[string]string{"": ""},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
		},
		{
			name:          "Empty input",
			input:         []byte{},
			existingData:  map[string]string{"": ""},
			writeError:    nil,
			expectedError: nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["Offerings"] == string(tt.input)
				})).Return(tt.writeError)
			} else if len(tt.input) != 4 {
				// For input whose input is not a valid yob, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
				return
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call save yob
			result, err := h.SaveOfferings(context.Background(), "save_offerings", tt.input)

			if err != nil {
				t.Fatalf("Failed to save offerings with error: %v", err)
			}
			savedData, err := h.accountFileHandler.ReadAccountData()
			if err == nil {
				//Assert that the input provided is what was saved into the file
				assert.Equal(t, string(tt.input), savedData["Offerings"])
			}

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}


func TestSaveGender(t *testing.T) {
	// Create a new instance of MockAccountFileHandler
	mockFileHandler := new(mocks.MockAccountFileHandler)

	// Define test cases
	tests := []struct {
		name           string
		input          []byte
		existingData   map[string]string
		writeError     error
		expectedResult resource.Result
		expectedError  error
		expectedGender string
	}{
		{
			name:           "Successful Save - Male",
			input:          []byte("1"),
			existingData:   map[string]string{"OtherKey": "OtherValue"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
			expectedGender: "Male",
		},
		{
			name:           "Successful Save - Female",
			input:          []byte("2"),
			existingData:   map[string]string{"OtherKey": "OtherValue"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
			expectedGender: "Female",
		},
		{
			name:           "Successful Save - Unspecified",
			input:          []byte("3"),
			existingData:   map[string]string{"OtherKey": "OtherValue"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
			expectedGender: "Unspecified",
		},
	
		{
			name:           "Empty Input",
			input:          []byte{},
			existingData:   map[string]string{"OtherKey": "OtherValue"},
			writeError:     nil,
			expectedResult: resource.Result{},
			expectedError:  nil,
			expectedGender: "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Set up the mock expectations
			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
			if tt.expectedError == nil && len(tt.input) > 0 {
				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["Gender"] == tt.expectedGender
				})).Return(tt.writeError)
			}  else if len(tt.input) == 0 {
				// For empty input, no WriteAccountData call should be made
				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
			}

			// Create the Handlers instance with the mock file handler
			h := &Handlers{
				accountFileHandler: mockFileHandler,
			}

			// Call the method
			result, err := h.SaveGender(context.Background(), "save_gender", tt.input)

			// Assert the results
			assert.Equal(t, tt.expectedResult, result)
			assert.Equal(t, tt.expectedError, err)

			// Verify WriteAccountData was called with the expected data
			if len(tt.input) > 0 && tt.expectedError == nil {
				mockFileHandler.AssertCalled(t, "WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
					return data["Gender"] == tt.expectedGender
				}))
			}

			// Assert all expectations were met
			mockFileHandler.AssertExpectations(t)
		})
	}
}

func TestGetSender(t *testing.T) {
	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
	h := &Handlers{
		accountFileHandler: mockAccountFileHandler,
	}

	tests := []struct {
		name           string
		expectedResult resource.Result
		accountData    map[string]string
	}{
		{
			name: "Valid public key",
			expectedResult: resource.Result{
				Content: "test-public-key",
			},
			accountData: map[string]string{
				"PublicKey": "test-public-key",
			},
		},
		{
			name: "Missing public key",
			expectedResult: resource.Result{
				Content: "",
			},
			accountData: map[string]string{},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Reset the mock state
			mockAccountFileHandler.Mock = mock.Mock{}

			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)

			result, err := h.GetSender(context.Background(), "", nil)

			if err != nil {
				t.Fatalf("Error occurred: %v", err)
			}

			assert.Equal(t, tt.expectedResult.Content, result.Content)
			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
		})
	}
}

func TestGetAmount(t *testing.T) {
	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
	h := &Handlers{
		accountFileHandler: mockAccountFileHandler,
	}

	tests := []struct {
		name           string
		expectedResult resource.Result
		accountData    map[string]string
	}{
		{
			name: "Valid amount",
			expectedResult: resource.Result{
				Content: "0.003",
			},
			accountData: map[string]string{
				"Amount": "0.003",
			},
		},
		{
			name:           "Missing amount",
			expectedResult: resource.Result{},
			accountData: map[string]string{
				"Amount": "",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Reset the mock state
			mockAccountFileHandler.Mock = mock.Mock{}

			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)

			result, err := h.GetAmount(context.Background(), "", nil)

			assert.NoError(t, err)
			assert.Equal(t, tt.expectedResult.Content, result.Content)

			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
		})
	}
}