package account

import (
	"context"
	"testing"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/internal/store/postgres"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
	"github.com/break/junhong_cmp_fiber/tests/testutils"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
)

type MockAuditService struct {
	mock.Mock
}

func (m *MockAuditService) LogOperation(ctx context.Context, log *model.AccountOperationLog) {
	m.Called(ctx, log)
}

type MockShopStore struct {
	mock.Mock
}

func (m *MockShopStore) GetByID(ctx context.Context, id uint) (*model.Shop, error) {
	args := m.Called(ctx, id)
	if args.Get(0) == nil {
		return nil, args.Error(1)
	}
	return args.Get(0).(*model.Shop), args.Error(1)
}

func (m *MockShopStore) GetSubordinateShopIDs(ctx context.Context, shopID uint) ([]uint, error) {
	args := m.Called(ctx, shopID)
	if args.Get(0) == nil {
		return nil, args.Error(1)
	}
	return args.Get(0).([]uint), args.Error(1)
}

type MockEnterpriseStore struct {
	mock.Mock
}

func (m *MockEnterpriseStore) GetByID(ctx context.Context, id uint) (*model.Enterprise, error) {
	args := m.Called(ctx, id)
	if args.Get(0) == nil {
		return nil, args.Error(1)
	}
	return args.Get(0).(*model.Enterprise), args.Error(1)
}

func TestAccountService_Create_SuperAdminSuccess(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_super_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, username, resp.Username)
	assert.Equal(t, phone, resp.Phone)
	assert.Equal(t, constants.UserTypePlatform, resp.UserType)
	assert.Equal(t, constants.StatusEnabled, resp.Status)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Create_PlatformUserCreatePlatformAccount(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	username := "test_platform_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, username, resp.Username)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Create_PlatformUserCreateAgentAccount(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	shopID := uint(1)
	username := "test_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, constants.UserTypeAgent, resp.UserType)
	assert.Equal(t, &shopID, resp.ShopID)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Create_AgentCreateSubordinateShopAccount(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	agentShopID := uint(10)
	subordinateShopID := uint(11)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeAgent,
		ShopID:   agentShopID,
	})

	username := "test_sub_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &subordinateShopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, agentShopID).Return([]uint{agentShopID, subordinateShopID}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, &subordinateShopID, resp.ShopID)

	mockShop.AssertCalled(t, "GetSubordinateShopIDs", mock.Anything, agentShopID)
	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Create_AgentCreateOtherShopAccountForbidden(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	agentShopID := uint(10)
	otherShopID := uint(99)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeAgent,
		ShopID:   agentShopID,
	})

	username := "test_forbidden_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &otherShopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, agentShopID).Return([]uint{agentShopID}, nil)

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Create_AgentCreatePlatformAccountForbidden(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	username := "test_platform_forbidden_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Create_EnterpriseUserForbidden(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:       1,
		UserType:     constants.UserTypeEnterprise,
		EnterpriseID: 1,
	})

	username := "test_enterprise_forbidden_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Create_UsernameDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_dup_" + time.Now().Format("20060102150405")
	phone1 := "1" + time.Now().Format("0601021504")
	phone2 := "1" + time.Now().Format("0601021505")

	req1 := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone1,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req1)
	require.NoError(t, err)

	req2 := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone2,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	_, err = svc.Create(ctx, req2)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUsernameExists, appErr.Code)
}

func TestAccountService_Create_PhoneDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	phone := "1" + time.Now().Format("0601021504")
	username1 := "test_phone_dup1_" + time.Now().Format("20060102150405")
	username2 := "test_phone_dup2_" + time.Now().Format("20060102150405")

	req1 := &dto.CreateAccountRequest{
		Username: username1,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req1)
	require.NoError(t, err)

	req2 := &dto.CreateAccountRequest{
		Username: username2,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	_, err = svc.Create(ctx, req2)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodePhoneExists, appErr.Code)
}

func TestAccountService_Create_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	username := "test_unauth_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

// ============ Update 方法测试 ============

func TestAccountService_Update_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	newUsername := "updated_" + time.Now().Format("20060102150405")
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, newUsername, updated.Username)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Update_NotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	newUsername := "test"
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	_, err := svc.Update(ctx, 99999, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Update_AgentUnauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_agent_unauth_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	newUsername := "updated"
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(10)).Return([]uint{10}, nil)

	_, err = svc.Update(agentCtx, created.ID, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Update_UsernameDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username1 := "test_dup1_" + time.Now().Format("20060102150405")
	username2 := "test_dup2_" + time.Now().Format("20060102150405")
	phone1 := "1" + time.Now().Format("0601021504")
	phone2 := "1" + time.Now().Format("0601021505")

	req1 := &dto.CreateAccountRequest{
		Username: username1,
		Phone:    phone1,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	req2 := &dto.CreateAccountRequest{
		Username: username2,
		Phone:    phone2,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	acc1, err := svc.Create(ctx, req1)
	require.NoError(t, err)

	_, err = svc.Create(ctx, req2)
	require.NoError(t, err)

	updateReq := &dto.UpdateAccountRequest{
		Username: &username2,
	}

	_, err = svc.Update(ctx, acc1.ID, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUsernameExists, appErr.Code)
}

func TestAccountService_Update_PhoneDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username1 := "test_phone_dup1_" + time.Now().Format("20060102150405")
	username2 := "test_phone_dup2_" + time.Now().Format("20060102150405")
	phone1 := "1" + time.Now().Format("0601021504")
	phone2 := "1" + time.Now().Format("0601021505")

	req1 := &dto.CreateAccountRequest{
		Username: username1,
		Phone:    phone1,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	req2 := &dto.CreateAccountRequest{
		Username: username2,
		Phone:    phone2,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	acc1, err := svc.Create(ctx, req1)
	require.NoError(t, err)

	_, err = svc.Create(ctx, req2)
	require.NoError(t, err)

	updateReq := &dto.UpdateAccountRequest{
		Phone: &phone2,
	}

	_, err = svc.Update(ctx, acc1.ID, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodePhoneExists, appErr.Code)
}

// ============ Delete 方法测试 ============

func TestAccountService_Delete_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_delete_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	err = svc.Delete(ctx, created.ID)
	require.NoError(t, err)

	_, err = svc.Get(ctx, created.ID)
	require.Error(t, err)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Delete_NotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	err := svc.Delete(ctx, 99999)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Delete_AgentUnauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_delete_unauth_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(10)).Return([]uint{10}, nil)

	err = svc.Delete(agentCtx, created.ID)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

// ============ AssignRoles 方法测试 ============

func TestAccountService_AssignRoles_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_assign_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_role_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	ars, err := svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.NoError(t, err)
	assert.Len(t, ars, 1)
	assert.Equal(t, created.ID, ars[0].AccountID)
	assert.Equal(t, role.ID, ars[0].RoleID)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_AssignRoles_SuperAdminForbidden(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_super_admin_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeSuperAdmin,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{1})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_AssignRoles_RoleTypeMismatch(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_role_mismatch_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   ptrUint(1),
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_platform_role_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_AssignRoles_EmptyArrayClearsRoles(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_clear_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_role_clear_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.NoError(t, err)

	ars, err := svc.AssignRoles(ctx, created.ID, []uint{})
	require.NoError(t, err)
	assert.Len(t, ars, 0)
}

// ============ RemoveRole 方法测试 ============

func TestAccountService_RemoveRole_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_remove_role_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_role_remove_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.NoError(t, err)

	err = svc.RemoveRole(ctx, created.ID, role.ID)
	require.NoError(t, err)

	roles, err := svc.GetRoles(ctx, created.ID)
	require.NoError(t, err)
	assert.Len(t, roles, 0)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_RemoveRole_AccountNotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	err := svc.RemoveRole(ctx, 99999, 1)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

// ============ GetRoles 方法测试 ============

func TestAccountService_GetRoles_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_get_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_role_get_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.NoError(t, err)

	roles, err := svc.GetRoles(ctx, created.ID)
	require.NoError(t, err)
	assert.Len(t, roles, 1)
	assert.Equal(t, role.ID, roles[0].ID)
}

func TestAccountService_GetRoles_EmptyArray(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_no_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	roles, err := svc.GetRoles(ctx, created.ID)
	require.NoError(t, err)
	assert.Len(t, roles, 0)
}

// ============ List 方法测试 ============

func TestAccountService_List_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_list_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.AccountListRequest{
		Page:     1,
		PageSize: 20,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_List_FilterByUsername(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_filter_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.AccountListRequest{
		Page:     1,
		PageSize: 20,
		Username: username,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
	assert.Equal(t, username, accounts[0].Username)
}

// ============ ValidatePassword 方法测试 ============

func TestAccountService_ValidatePassword_Correct(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	password := "TestPass123"
	username := "test_validate_pwd_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: password,
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	isValid := svc.ValidatePassword(password, created.Password)
	assert.True(t, isValid)
}

func TestAccountService_ValidatePassword_Incorrect(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	password := "TestPass123"
	username := "test_validate_pwd_wrong_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: password,
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	isValid := svc.ValidatePassword("WrongPassword", created.Password)
	assert.False(t, isValid)
}

// ============ UpdatePassword 方法测试 ============

func TestAccountService_UpdatePassword_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	password := "TestPass123"
	username := "test_update_pwd_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: password,
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	newPassword := "NewPass456"
	err = svc.UpdatePassword(ctx, created.ID, newPassword)
	require.NoError(t, err)

	updated, err := svc.Get(ctx, created.ID)
	require.NoError(t, err)

	isValid := svc.ValidatePassword(newPassword, updated.Password)
	assert.True(t, isValid)

	isOldValid := svc.ValidatePassword(password, updated.Password)
	assert.False(t, isOldValid)
}

// ============ UpdateStatus 方法测试 ============

func TestAccountService_UpdateStatus_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_status_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.Equal(t, constants.StatusEnabled, created.Status)

	err = svc.UpdateStatus(ctx, created.ID, constants.StatusDisabled)
	require.NoError(t, err)

	updated, err := svc.Get(ctx, created.ID)
	require.NoError(t, err)
	assert.Equal(t, constants.StatusDisabled, updated.Status)
}

// ============ 辅助函数 ============

func TestAccountService_Get_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_get_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	retrieved, err := svc.Get(ctx, created.ID)
	require.NoError(t, err)
	assert.Equal(t, created.ID, retrieved.ID)
	assert.Equal(t, username, retrieved.Username)
}

func TestAccountService_Get_NotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	_, err := svc.Get(ctx, 99999)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeAccountNotFound, appErr.Code)
}

func TestAccountService_UpdatePassword_AccountNotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	err := svc.UpdatePassword(ctx, 99999, "NewPass456")
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeAccountNotFound, appErr.Code)
}

func TestAccountService_UpdateStatus_AccountNotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	err := svc.UpdateStatus(ctx, 99999, constants.StatusDisabled)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeAccountNotFound, appErr.Code)
}

func TestAccountService_UpdatePassword_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	err := svc.UpdatePassword(ctx, 1, "NewPass456")
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_UpdateStatus_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	err := svc.UpdateStatus(ctx, 1, constants.StatusDisabled)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_Delete_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	err := svc.Delete(ctx, 1)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_AssignRoles_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	_, err := svc.AssignRoles(ctx, 1, []uint{1})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_RemoveRole_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	err := svc.RemoveRole(ctx, 1, 1)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_Update_Unauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	newUsername := "test"
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	_, err := svc.Update(ctx, 1, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUnauthorized, appErr.Code)
}

func TestAccountService_AssignRoles_NotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	_, err := svc.AssignRoles(ctx, 99999, []uint{1})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_GetRoles_NotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	_, err := svc.GetRoles(ctx, 99999)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeAccountNotFound, appErr.Code)
}

func TestAccountService_List_FilterByUserType(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_filter_type_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	userType := constants.UserTypePlatform
	listReq := &dto.AccountListRequest{
		Page:     1,
		PageSize: 20,
		UserType: &userType,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_List_FilterByStatus(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_filter_status_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	status := constants.StatusEnabled
	listReq := &dto.AccountListRequest{
		Page:     1,
		PageSize: 20,
		Status:   &status,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_List_FilterByPhone(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_filter_phone_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.AccountListRequest{
		Page:     1,
		PageSize: 20,
		Phone:    phone,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_Update_UpdatePassword(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_pwd_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	newPassword := "NewPass456"
	updateReq := &dto.UpdateAccountRequest{
		Password: &newPassword,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)

	isValid := svc.ValidatePassword(newPassword, updated.Password)
	assert.True(t, isValid)
}

func TestAccountService_Update_UpdateStatus(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_status_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	status := constants.StatusDisabled
	updateReq := &dto.UpdateAccountRequest{
		Status: &status,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, constants.StatusDisabled, updated.Status)
}

func TestAccountService_Update_UpdatePhone(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_phone_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	newPhone := "1" + time.Now().Format("0601021505")
	updateReq := &dto.UpdateAccountRequest{
		Phone: &newPhone,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, newPhone, updated.Phone)
}

func TestAccountService_AssignRoles_AgentUnauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_agent_assign_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(10)).Return([]uint{10}, nil)

	_, err = svc.AssignRoles(agentCtx, created.ID, []uint{1})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Create_EnterpriseAccountSuccess(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	enterpriseID := uint(1)
	username := "test_enterprise_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username:     username,
		Phone:        phone,
		Password:     "TestPass123",
		UserType:     constants.UserTypeEnterprise,
		EnterpriseID: &enterpriseID,
	}

	mockEnterprise.On("GetByID", mock.Anything, enterpriseID).Return(&model.Enterprise{}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, constants.UserTypeEnterprise, resp.UserType)
	assert.Equal(t, &enterpriseID, resp.EnterpriseID)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Create_AgentMissingShopID(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	username := "test_agent_no_shop_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
	}

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_Create_EnterpriseMissingEnterpriseID(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	username := "test_enterprise_no_id_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeEnterprise,
	}

	_, err := svc.Create(ctx, req)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_RemoveRole_AgentUnauthorized(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_remove_role_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(10)).Return([]uint{10}, nil)

	err = svc.RemoveRole(agentCtx, created.ID, 1)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_AssignRoles_MultipleRoles(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_multi_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role1 := &model.Role{
		RoleName: "test_role1_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role1)
	require.NoError(t, errRole)

	role2 := &model.Role{
		RoleName: "test_role2_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole = roleStore.Create(ctx, role2)
	require.NoError(t, errRole)

	ars, err := svc.AssignRoles(ctx, created.ID, []uint{role1.ID, role2.ID})
	require.NoError(t, err)
	assert.Len(t, ars, 2)

	roles, err := svc.GetRoles(ctx, created.ID)
	require.NoError(t, err)
	assert.Len(t, roles, 2)
}

func TestAccountService_Update_AllFields(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_all_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	newUsername := "updated_" + time.Now().Format("20060102150405")
	newPhone := "1" + time.Now().Format("0601021505")
	newPassword := "NewPass456"
	newStatus := constants.StatusDisabled

	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
		Phone:    &newPhone,
		Password: &newPassword,
		Status:   &newStatus,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, newUsername, updated.Username)
	assert.Equal(t, newPhone, updated.Phone)
	assert.Equal(t, newStatus, updated.Status)

	isValid := svc.ValidatePassword(newPassword, updated.Password)
	assert.True(t, isValid)
}

func TestAccountService_ListPlatformAccounts_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_platform_list_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.PlatformAccountListRequest{
		Page:     1,
		PageSize: 20,
	}

	accounts, total, err := svc.ListPlatformAccounts(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_CreateSystemAccount_Success(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	username := "test_system_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	account := &model.Account{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account)
	require.NoError(t, err)
	assert.NotZero(t, account.ID)
}

func TestAccountService_CreateSystemAccount_MissingUsername(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	account := &model.Account{
		Username: "",
		Phone:    "13800000000",
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_CreateSystemAccount_MissingPhone(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	account := &model.Account{
		Username: "test_system",
		Phone:    "",
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_CreateSystemAccount_MissingPassword(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	account := &model.Account{
		Username: "test_system",
		Phone:    "13800000000",
		Password: "",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeInvalidParam, appErr.Code)
}

func TestAccountService_CreateSystemAccount_UsernameDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	username := "test_system_dup_" + time.Now().Format("20060102150405")
	phone1 := "1" + time.Now().Format("0601021504")
	phone2 := "1" + time.Now().Format("0601021505")

	account1 := &model.Account{
		Username: username,
		Phone:    phone1,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account1)
	require.NoError(t, err)

	account2 := &model.Account{
		Username: username,
		Phone:    phone2,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err = svc.CreateSystemAccount(ctx, account2)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeUsernameExists, appErr.Code)
}

func TestAccountService_CreateSystemAccount_PhoneDuplicate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := context.Background()

	username1 := "test_system_phone1_" + time.Now().Format("20060102150405")
	username2 := "test_system_phone2_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	account1 := &model.Account{
		Username: username1,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err := svc.CreateSystemAccount(ctx, account1)
	require.NoError(t, err)

	account2 := &model.Account{
		Username: username2,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
		Status:   constants.StatusEnabled,
	}

	err = svc.CreateSystemAccount(ctx, account2)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodePhoneExists, appErr.Code)
}

func TestAccountService_ListPlatformAccounts_FilterByUsername(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_platform_filter_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.PlatformAccountListRequest{
		Page:     1,
		PageSize: 20,
		Username: username,
	}

	accounts, total, err := svc.ListPlatformAccounts(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_ListPlatformAccounts_FilterByPhone(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_platform_phone_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	listReq := &dto.PlatformAccountListRequest{
		Page:     1,
		PageSize: 20,
		Phone:    phone,
	}

	accounts, total, err := svc.ListPlatformAccounts(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_ListPlatformAccounts_FilterByStatus(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_platform_status_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	_, err := svc.Create(ctx, req)
	require.NoError(t, err)

	status := constants.StatusEnabled
	listReq := &dto.PlatformAccountListRequest{
		Page:     1,
		PageSize: 20,
		Status:   &status,
	}

	accounts, total, err := svc.ListPlatformAccounts(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_Create_PlatformUserCreateEnterpriseAccount(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	enterpriseID := uint(1)
	username := "test_enterprise_create_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username:     username,
		Phone:        phone,
		Password:     "TestPass123",
		UserType:     constants.UserTypeEnterprise,
		EnterpriseID: &enterpriseID,
	}

	mockEnterprise.On("GetByID", mock.Anything, enterpriseID).Return(&model.Enterprise{}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, constants.UserTypeEnterprise, resp.UserType)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_List_DefaultPagination(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	listReq := &dto.AccountListRequest{
		Page:     0,
		PageSize: 0,
	}

	accounts, total, err := svc.List(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_ListPlatformAccounts_DefaultPagination(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	listReq := &dto.PlatformAccountListRequest{
		Page:     0,
		PageSize: 0,
	}

	accounts, total, err := svc.ListPlatformAccounts(ctx, listReq)
	require.NoError(t, err)
	assert.Greater(t, total, int64(0))
	assert.Greater(t, len(accounts), 0)
}

func TestAccountService_AssignRoles_RoleNotFound(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_role_not_found_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	_, err = svc.AssignRoles(ctx, created.ID, []uint{99999})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeRoleNotFound, appErr.Code)
}

func TestAccountService_Update_SameUsername(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_same_username_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	updateReq := &dto.UpdateAccountRequest{
		Username: &username,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, username, updated.Username)
}

func TestAccountService_Update_SamePhone(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_same_phone_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	updateReq := &dto.UpdateAccountRequest{
		Phone: &phone,
	}

	updated, err := svc.Update(ctx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, phone, updated.Phone)
}

func TestAccountService_AssignRoles_DuplicateRoles(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_dup_roles_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_role_dup_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypePlatform,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	ars, err := svc.AssignRoles(ctx, created.ID, []uint{role.ID, role.ID})
	require.NoError(t, err)
	assert.Len(t, ars, 1)
}

func TestAccountService_Create_PlatformUserCreateAgentWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	shopID := uint(1)
	username := "test_agent_shop_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, constants.UserTypeAgent, resp.UserType)
	assert.Equal(t, &shopID, resp.ShopID)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_AssignRoles_CustomerAccountType(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	shopID := uint(1)
	username := "test_agent_role_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(ctx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_customer_role_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypeCustomer,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(ctx, role)
	require.NoError(t, errRole)

	ars, err := svc.AssignRoles(ctx, created.ID, []uint{role.ID})
	require.NoError(t, err)
	assert.Len(t, ars, 1)
}

func TestAccountService_Delete_AgentAccountWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	shopID := uint(1)
	username := "test_delete_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   1,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)

	err = svc.Delete(agentCtx, created.ID)
	require.NoError(t, err)

	_, err = svc.Get(superAdminCtx, created.ID)
	require.Error(t, err)
}

func TestAccountService_Update_AgentAccountWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	shopID := uint(1)
	username := "test_update_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   1,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)

	newUsername := "updated_agent_" + time.Now().Format("20060102150405")
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	updated, err := svc.Update(agentCtx, created.ID, updateReq)
	require.NoError(t, err)
	assert.Equal(t, newUsername, updated.Username)
}

func TestAccountService_AssignRoles_AgentAccountWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	shopID := uint(1)
	username := "test_assign_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_agent_role_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypeCustomer,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(superAdminCtx, role)
	require.NoError(t, errRole)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   1,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)

	ars, err := svc.AssignRoles(agentCtx, created.ID, []uint{role.ID})
	require.NoError(t, err)
	assert.Len(t, ars, 1)
}

func TestAccountService_RemoveRole_AgentAccountWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	shopID := uint(1)
	username := "test_remove_agent_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypeAgent,
		ShopID:   &shopID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	role := &model.Role{
		RoleName: "test_remove_agent_role_" + time.Now().Format("20060102150405"),
		RoleType: constants.RoleTypeCustomer,
		Status:   constants.StatusEnabled,
	}
	errRole := roleStore.Create(superAdminCtx, role)
	require.NoError(t, errRole)

	_, err = svc.AssignRoles(superAdminCtx, created.ID, []uint{role.ID})
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   1,
	})

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)

	err = svc.RemoveRole(agentCtx, created.ID, role.ID)
	require.NoError(t, err)

	roles, err := svc.GetRoles(superAdminCtx, created.ID)
	require.NoError(t, err)
	assert.Len(t, roles, 0)
}

func TestAccountService_Create_EnterpriseAccountWithShop(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypePlatform,
	})

	shopID := uint(1)
	enterpriseID := uint(1)
	username := "test_enterprise_shop_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username:     username,
		Phone:        phone,
		Password:     "TestPass123",
		UserType:     constants.UserTypeEnterprise,
		ShopID:       &shopID,
		EnterpriseID: &enterpriseID,
	}

	mockShop.On("GetSubordinateShopIDs", mock.Anything, uint(1)).Return([]uint{1}, nil)
	mockEnterprise.On("GetByID", mock.Anything, enterpriseID).Return(&model.Enterprise{}, nil)
	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	resp, err := svc.Create(ctx, req)
	require.NoError(t, err)
	assert.NotZero(t, resp.ID)
	assert.Equal(t, constants.UserTypeEnterprise, resp.UserType)
	assert.Equal(t, &enterpriseID, resp.EnterpriseID)

	mockAudit.AssertCalled(t, "LogOperation", mock.Anything, mock.Anything)
}

func TestAccountService_Delete_PlatformAccountByAgent(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_delete_platform_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	err = svc.Delete(agentCtx, created.ID)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_Update_PlatformAccountByAgent(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_update_platform_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	newUsername := "updated"
	updateReq := &dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	_, err = svc.Update(agentCtx, created.ID, updateReq)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_AssignRoles_PlatformAccountByAgent(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_assign_platform_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	_, err = svc.AssignRoles(agentCtx, created.ID, []uint{1})
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func TestAccountService_RemoveRole_PlatformAccountByAgent(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)

	accountStore := postgres.NewAccountStore(tx, rdb)
	roleStore := postgres.NewRoleStore(tx)
	accountRoleStore := postgres.NewAccountRoleStore(tx, rdb)
	mockAudit := new(MockAuditService)
	mockShop := new(MockShopStore)
	mockEnterprise := new(MockEnterpriseStore)

	svc := New(accountStore, roleStore, accountRoleStore, mockShop, mockEnterprise, mockAudit)

	superAdminCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   1,
		UserType: constants.UserTypeSuperAdmin,
	})

	username := "test_remove_platform_" + time.Now().Format("20060102150405")
	phone := "1" + time.Now().Format("0601021504")

	req := &dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "TestPass123",
		UserType: constants.UserTypePlatform,
	}

	mockAudit.On("LogOperation", mock.Anything, mock.Anything).Return()

	created, err := svc.Create(superAdminCtx, req)
	require.NoError(t, err)

	agentCtx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{
		UserID:   2,
		UserType: constants.UserTypeAgent,
		ShopID:   10,
	})

	err = svc.RemoveRole(agentCtx, created.ID, 1)
	require.Error(t, err)
	appErr, ok := err.(*errors.AppError)
	require.True(t, ok)
	assert.Equal(t, errors.CodeForbidden, appErr.Code)
}

func ptrUint(v uint) *uint {
	return &v
}
