package integration

import (
	"encoding/json"
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/response"
	"github.com/break/junhong_cmp_fiber/tests/testutils/integ"
)

// =============================================================================
// 平台账号管理测试
// =============================================================================

func TestPlatformAccount_Create(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	username := fmt.Sprintf("platform_user_%d", time.Now().UnixNano())
	phone := fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000)

	reqBody := dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "Password123",
		UserType: constants.UserTypePlatform,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)

	var count int64
	env.RawDB().Model(&model.Account{}).Where("username = ?", username).Count(&count)
	assert.Equal(t, int64(1), count)
}

func TestPlatformAccount_Create_DuplicateUsername(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	existingAccount := env.CreateTestAccount("existing_platform", "password123", constants.UserTypePlatform, nil, nil)

	phone := fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000)
	reqBody := dto.CreateAccountRequest{
		Username: existingAccount.Username,
		Phone:    phone,
		Password: "Password123",
		UserType: constants.UserTypePlatform,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, errors.CodeUsernameExists, result.Code)
}

func TestPlatformAccount_List(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	for i := 1; i <= 3; i++ {
		env.CreateTestAccount(fmt.Sprintf("platform_list_%d", i), "password123", constants.UserTypePlatform, nil, nil)
	}

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)

	data := result.Data.(map[string]interface{})
	items := data["items"].([]interface{})
	assert.GreaterOrEqual(t, len(items), 3)
}

func TestPlatformAccount_Get(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testAccount := env.CreateTestAccount("platform_detail", "password123", constants.UserTypePlatform, nil, nil)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestPlatformAccount_Get_NotFound(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts/99999", nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, errors.CodeAccountNotFound, result.Code)
}

func TestPlatformAccount_Update(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testAccount := env.CreateTestAccount("platform_update", "password123", constants.UserTypePlatform, nil, nil)

	newUsername := fmt.Sprintf("updated_%d", time.Now().UnixNano())
	reqBody := dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestPlatformAccount_UpdatePassword(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testAccount := env.CreateTestAccount("platform_pwd", "password123", constants.UserTypePlatform, nil, nil)

	reqBody := dto.UpdatePasswordRequest{
		NewPassword: "NewPassword@123",
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestPlatformAccount_UpdateStatus(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testAccount := env.CreateTestAccount("platform_status", "password123", constants.UserTypePlatform, nil, nil)

	reqBody := dto.UpdateStatusRequest{
		Status: constants.StatusDisabled,
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestPlatformAccount_Delete(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testAccount := env.CreateTestAccount("platform_delete", "password123", constants.UserTypePlatform, nil, nil)

	resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

// =============================================================================
// 代理账号管理测试
// =============================================================================

func TestShopAccount_Create(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理账号测试店铺", 1, nil)

	username := fmt.Sprintf("agent_user_%d", time.Now().UnixNano())
	phone := fmt.Sprintf("139%08d", time.Now().UnixNano()%100000000)

	reqBody := dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "Password123",
		UserType: constants.UserTypeAgent,
		ShopID:   &testShop.ID,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
	assert.NotNil(t, result.Data)
}

func TestShopAccount_Create_MissingShopID(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	username := fmt.Sprintf("agent_no_shop_%d", time.Now().UnixNano())
	phone := fmt.Sprintf("139%08d", time.Now().UnixNano()%100000000)

	reqBody := dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "Password123",
		UserType: constants.UserTypeAgent,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.NotEqual(t, 0, result.Code, "创建代理账号缺少店铺ID应返回错误")
}

func TestShopAccount_List(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理列表测试店铺", 1, nil)

	for i := 1; i <= 3; i++ {
		env.CreateTestAccount(fmt.Sprintf("agent_list_%d", i), "password123", constants.UserTypeAgent, &testShop.ID, nil)
	}

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)

	data := result.Data.(map[string]interface{})
	items := data["items"].([]interface{})
	assert.GreaterOrEqual(t, len(items), 3)
}

func TestShopAccount_Get(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理详情测试店铺", 1, nil)
	testAccount := env.CreateTestAccount("agent_detail", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestShopAccount_Update(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理更新测试店铺", 1, nil)
	testAccount := env.CreateTestAccount("agent_update", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	newUsername := fmt.Sprintf("updated_agent_%d", time.Now().UnixNano())
	reqBody := dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestShopAccount_UpdatePassword(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理密码测试店铺", 1, nil)
	testAccount := env.CreateTestAccount("agent_pwd", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	reqBody := dto.UpdatePasswordRequest{
		NewPassword: "NewPassword@456",
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestShopAccount_UpdateStatus(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理状态测试店铺", 1, nil)
	testAccount := env.CreateTestAccount("agent_status", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	reqBody := dto.UpdateStatusRequest{
		Status: constants.StatusDisabled,
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestShopAccount_Delete(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理删除测试店铺", 1, nil)
	testAccount := env.CreateTestAccount("agent_delete", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

// =============================================================================
// 企业账号管理测试
// =============================================================================

func TestEnterpriseAccount_Create(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业账号测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("测试企业", &testShop.ID)

	username := fmt.Sprintf("enterprise_user_%d", time.Now().UnixNano())
	phone := fmt.Sprintf("137%08d", time.Now().UnixNano()%100000000)

	reqBody := dto.CreateAccountRequest{
		Username:     username,
		Phone:        phone,
		Password:     "Password123",
		UserType:     constants.UserTypeEnterprise,
		EnterpriseID: &testEnterprise.ID,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
	assert.NotNil(t, result.Data)
}

func TestEnterpriseAccount_Create_MissingEnterpriseID(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	username := fmt.Sprintf("enterprise_no_ent_%d", time.Now().UnixNano())
	phone := fmt.Sprintf("137%08d", time.Now().UnixNano()%100000000)

	reqBody := dto.CreateAccountRequest{
		Username: username,
		Phone:    phone,
		Password: "Password123",
		UserType: constants.UserTypeEnterprise,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.NotEqual(t, 0, result.Code, "创建企业账号缺少企业ID应返回错误")
}

func TestEnterpriseAccount_List(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业列表测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("列表测试企业", &testShop.ID)

	for i := 1; i <= 3; i++ {
		env.CreateTestAccount(fmt.Sprintf("ent_list_%d", i), "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
	}

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)

	data := result.Data.(map[string]interface{})
	items := data["items"].([]interface{})
	assert.GreaterOrEqual(t, len(items), 3)
}

func TestEnterpriseAccount_Get(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业详情测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("详情测试企业", &testShop.ID)
	testAccount := env.CreateTestAccount("ent_detail", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestEnterpriseAccount_Update(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业更新测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("更新测试企业", &testShop.ID)
	testAccount := env.CreateTestAccount("ent_update", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	newUsername := fmt.Sprintf("updated_ent_%d", time.Now().UnixNano())
	reqBody := dto.UpdateAccountRequest{
		Username: &newUsername,
	}

	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestEnterpriseAccount_UpdatePassword(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业密码测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("密码测试企业", &testShop.ID)
	testAccount := env.CreateTestAccount("ent_pwd", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	reqBody := dto.UpdatePasswordRequest{
		NewPassword: "NewPassword@789",
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestEnterpriseAccount_UpdateStatus(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业状态测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("状态测试企业", &testShop.ID)
	testAccount := env.CreateTestAccount("ent_status", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	reqBody := dto.UpdateStatusRequest{
		Status: constants.StatusDisabled,
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestEnterpriseAccount_Delete(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业删除测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("删除测试企业", &testShop.ID)
	testAccount := env.CreateTestAccount("ent_delete", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestEnterpriseAccount_Forbidden(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业禁止测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("禁止测试企业", &testShop.ID)
	entAccount := env.CreateTestAccount("ent_forbidden", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	resp, err := env.AsUser(entAccount).Request("GET", "/api/admin/accounts", nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, errors.CodeForbidden, result.Code, "企业用户应禁止访问账号管理功能")
}

// =============================================================================
// 角色管理测试（所有账号类型）
// =============================================================================

func TestAccount_AssignRoles_Platform(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	platformRole := env.CreateTestRole("平台角色", constants.RoleTypePlatform)
	testAccount := env.CreateTestAccount("role_platform", "password123", constants.UserTypePlatform, nil, nil)

	reqBody := dto.AssignRolesRequest{
		RoleIDs: []uint{platformRole.ID},
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_GetRoles_Platform(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	platformRole := env.CreateTestRole("平台角色获取", constants.RoleTypePlatform)
	testAccount := env.CreateTestAccount("role_platform_get", "password123", constants.UserTypePlatform, nil, nil)

	accountRole := &model.AccountRole{
		AccountID: testAccount.ID,
		RoleID:    platformRole.ID,
		Status:    constants.StatusEnabled,
		Creator:   1,
		Updater:   1,
	}
	env.TX.Create(accountRole)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_ClearRoles_Platform(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	platformRole := env.CreateTestRole("平台角色清空", constants.RoleTypePlatform)
	testAccount := env.CreateTestAccount("role_platform_clr", "password123", constants.UserTypePlatform, nil, nil)

	accountRole := &model.AccountRole{
		AccountID: testAccount.ID,
		RoleID:    platformRole.ID,
		Status:    constants.StatusEnabled,
		Creator:   1,
		Updater:   1,
	}
	env.TX.Create(accountRole)

	reqBody := dto.AssignRolesRequest{
		RoleIDs: []uint{},
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_SuperAdminCannotAssignRoles(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	platformRole := env.CreateTestRole("禁止分配角色", constants.RoleTypePlatform)
	superAdmin := env.CreateTestAccount("superadmin_role", "password123", constants.UserTypeSuperAdmin, nil, nil)

	reqBody := dto.AssignRolesRequest{
		RoleIDs: []uint{platformRole.ID},
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", superAdmin.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, errors.CodeInvalidParam, result.Code)
	assert.Contains(t, result.Message, "超级管理员不允许分配角色")
}

func TestAccount_AssignRoles_Shop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理角色测试店铺", 1, nil)
	agentRole := env.CreateTestRole("代理角色", constants.RoleTypeCustomer)
	testAccount := env.CreateTestAccount("role_agent", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	reqBody := dto.AssignRolesRequest{
		RoleIDs: []uint{agentRole.ID},
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_GetRoles_Shop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("代理获取角色测试店铺", 1, nil)
	agentRole := env.CreateTestRole("代理获取角色", constants.RoleTypeCustomer)
	testAccount := env.CreateTestAccount("role_agent_get", "password123", constants.UserTypeAgent, &testShop.ID, nil)

	accountRole := &model.AccountRole{
		AccountID: testAccount.ID,
		RoleID:    agentRole.ID,
		Status:    constants.StatusEnabled,
		Creator:   1,
		Updater:   1,
	}
	env.TX.Create(accountRole)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_AssignRoles_Enterprise(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业角色测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("角色测试企业", &testShop.ID)
	entRole := env.CreateTestRole("企业角色", constants.RoleTypeCustomer)
	testAccount := env.CreateTestAccount("role_ent", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	reqBody := dto.AssignRolesRequest{
		RoleIDs: []uint{entRole.ID},
	}
	jsonBody, _ := json.Marshal(reqBody)
	resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

func TestAccount_GetRoles_Enterprise(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	testShop := env.CreateTestShop("企业获取角色测试店铺", 1, nil)
	testEnterprise := env.CreateTestEnterprise("获取角色测试企业", &testShop.ID)
	entRole := env.CreateTestRole("企业获取角色", constants.RoleTypeCustomer)
	testAccount := env.CreateTestAccount("role_ent_get", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)

	accountRole := &model.AccountRole{
		AccountID: testAccount.ID,
		RoleID:    entRole.ID,
		Status:    constants.StatusEnabled,
		Creator:   1,
		Updater:   1,
	}
	env.TX.Create(accountRole)

	resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, fiber.StatusOK, resp.StatusCode)

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, 0, result.Code)
}

// =============================================================================
// 通用场景测试
// =============================================================================

func TestAccount_Unauthorized_Platform(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}

func TestAccount_Unauthorized_Shop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}

func TestAccount_Unauthorized_Enterprise(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
	require.NoError(t, err)
	defer resp.Body.Close()
	assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}

func TestAccount_InvalidID(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts/invalid", nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	var result response.Response
	err = json.NewDecoder(resp.Body).Decode(&result)
	require.NoError(t, err)
	assert.Equal(t, errors.CodeInvalidParam, result.Code)
}
