package integration

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

	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/pkg/response"
	"github.com/break/junhong_cmp_fiber/tests/testutils"
	"github.com/break/junhong_cmp_fiber/tests/testutils/integ"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

// TestShopManagement_CreateShop 测试创建商户
func TestShopManagement_CreateShop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 使用时间戳生成唯一的店铺名和代码
	timestamp := time.Now().UnixNano()
	shopName := fmt.Sprintf("test_shop_%d", timestamp)
	shopCode := fmt.Sprintf("SHOP%d", timestamp%1000000)

	reqBody := dto.CreateShopRequest{
		ShopName:     shopName,
		ShopCode:     shopCode,
		InitUsername: "testuser",
		InitPhone:    testutils.GenerateUniquePhone(),
		InitPassword: "password123",
	}

	body, err := json.Marshal(reqBody)
	require.NoError(t, err)

	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/shops", body)
	require.NoError(t, err)
	defer resp.Body.Close()

	t.Logf("HTTP 状态码: %d", resp.StatusCode)

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

	t.Logf("响应 Code: %d, Message: %s", result.Code, result.Message)
	t.Logf("响应 Data: %+v", result.Data)

	if result.Code != 0 {
		t.Fatalf("API 返回错误: %s", result.Message)
	}

	assert.Equal(t, 200, resp.StatusCode)
	assert.Equal(t, 0, result.Code)
	assert.NotNil(t, result.Data)

	shopData, ok := result.Data.(map[string]interface{})
	require.True(t, ok)
	assert.Equal(t, shopName, shopData["shop_name"])
	assert.Equal(t, shopCode, shopData["shop_code"])
	assert.Equal(t, float64(1), shopData["level"])
	assert.Equal(t, float64(1), shopData["status"])
}

// TestShopManagement_CreateShop_DuplicateCode 测试创建商户 - 商户编码重复
func TestShopManagement_CreateShop_DuplicateCode(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 使用时间戳生成唯一的店铺代码
	timestamp := time.Now().UnixNano()
	duplicateCode := fmt.Sprintf("DUP%d", timestamp%1000000)

	firstReq := dto.CreateShopRequest{
		ShopName:     fmt.Sprintf("shop1_%d", timestamp),
		ShopCode:     duplicateCode,
		InitUsername: fmt.Sprintf("dupuser1_%d", timestamp),
		InitPhone:    testutils.GenerateUniquePhone(),
		InitPassword: "password123",
	}
	firstBody, _ := json.Marshal(firstReq)
	firstResp, _ := env.AsSuperAdmin().Request("POST", "/api/admin/shops", firstBody)
	var firstResult response.Response
	json.NewDecoder(firstResp.Body).Decode(&firstResult)
	firstResp.Body.Close()

	require.Equal(t, 0, firstResult.Code, "第一个商户应该创建成功")

	reqBody := dto.CreateShopRequest{
		ShopName:     fmt.Sprintf("shop2_%d", timestamp),
		ShopCode:     duplicateCode,
		InitUsername: fmt.Sprintf("dupuser2_%d", timestamp),
		InitPhone:    testutils.GenerateUniquePhone(),
		InitPassword: "password123",
	}

	body, err := json.Marshal(reqBody)
	require.NoError(t, err)

	resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/shops", body)
	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)        // 非成功状态
	assert.Contains(t, result.Message, "已存在") // 错误消息应包含"已存在"
}

// TestShopManagement_ListShops 测试查询商户列表
func TestShopManagement_ListShops(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 创建测试数据
	env.CreateTestShop("商户A", 1, nil)
	env.CreateTestShop("商户B", 1, nil)
	env.CreateTestShop("商户C", 2, nil)

	resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/shops?page=1&size=10", nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	assert.Equal(t, 200, resp.StatusCode)

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

	assert.Equal(t, 0, result.Code)

	// 解析分页数据
	dataMap, ok := result.Data.(map[string]interface{})
	require.True(t, ok)

	items, ok := dataMap["items"].([]interface{})
	require.True(t, ok)
	assert.GreaterOrEqual(t, len(items), 3)
}

// TestShopManagement_UpdateShop 测试更新商户
func TestShopManagement_UpdateShop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 创建测试商户
	shop := env.CreateTestShop("原始商户", 1, nil)

	// 更新商户
	reqBody := dto.UpdateShopRequest{
		ShopName: "更新后的商户",
		Status:   1,
	}

	body, err := json.Marshal(reqBody)
	require.NoError(t, err)

	resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/shops/%d", shop.ID), body)
	require.NoError(t, err)
	defer resp.Body.Close()

	assert.Equal(t, 200, 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)

	shopData, ok := result.Data.(map[string]interface{})
	require.True(t, ok)
	assert.Equal(t, "更新后的商户", shopData["shop_name"])
}

// TestShopManagement_DeleteShop 测试删除商户
func TestShopManagement_DeleteShop(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 创建测试商户
	shop := env.CreateTestShop("待删除商户", 1, nil)

	// 删除商户
	resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/shops/%d", shop.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	assert.Equal(t, 200, resp.StatusCode)

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

	assert.Equal(t, 0, result.Code)
}

// TestShopManagement_DeleteShop_WithMultipleAccounts 测试删除商户 - 多个关联账号
func TestShopManagement_DeleteShop_WithMultipleAccounts(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 创建测试商户
	shop := env.CreateTestShop("多账号商户", 1, nil)

	// 删除商户
	resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/shops/%d", shop.ID), nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	assert.Equal(t, 200, resp.StatusCode)

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

	assert.Equal(t, 0, result.Code)
}

// TestShopManagement_Unauthorized 测试未认证访问
func TestShopManagement_Unauthorized(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 不提供 token
	resp, err := env.ClearAuth().Request("GET", "/api/admin/shops", nil)
	require.NoError(t, err)
	defer resp.Body.Close()

	// 应该返回 401 未授权
	assert.Equal(t, 401, resp.StatusCode)
}

// TestShopManagement_InvalidToken 测试无效 token
func TestShopManagement_InvalidToken(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	// 提供无效 token
	resp, err := env.RequestWithHeaders("GET", "/api/admin/shops", nil, map[string]string{
		"Authorization": "Bearer invalid-token-12345",
	})
	require.NoError(t, err)
	defer resp.Body.Close()

	// 应该返回 401 未授权
	assert.Equal(t, 401, resp.StatusCode)
}
