package integration

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

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

// TestGatewayDevice_GetInfo 测试查询设备信息接口
func TestGatewayDevice_GetInfo(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000001",
		DeviceName:  "测试设备1",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功查询设备信息", func(t *testing.T) {
		resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/devices/by-imei/%s/gateway-info", device.DeviceNo), 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)
	})

	t.Run("无权限访问其他店铺的设备信息", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺8",
			ShopCode: "SHOP_008",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000002",
			DeviceName:  "测试设备2",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_1",
			Phone:    "13800000201",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		resp, err := env.AsUser(agentAccount).Request("GET", fmt.Sprintf("/api/admin/devices/by-imei/%s/gateway-info", device.DeviceNo), nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_GetSlots 测试查询卡槽信息接口
func TestGatewayDevice_GetSlots(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000003",
		DeviceName:  "测试设备3",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功查询卡槽信息", func(t *testing.T) {
		resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/devices/by-imei/%s/gateway-slots", device.DeviceNo), 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)
	})

	t.Run("无权限访问其他店铺的卡槽信息", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺9",
			ShopCode: "SHOP_009",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000004",
			DeviceName:  "测试设备4",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_2",
			Phone:    "13800000202",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		resp, err := env.AsUser(agentAccount).Request("GET", fmt.Sprintf("/api/admin/devices/by-imei/%s/gateway-slots", device.DeviceNo), nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_SetSpeedLimit 测试设置限速接口
func TestGatewayDevice_SetSpeedLimit(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000005",
		DeviceName:  "测试设备5",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功设置限速", func(t *testing.T) {
		body := []byte(`{"uploadSpeed": 1024, "downloadSpeed": 2048}`)
		resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/devices/by-imei/%s/speed-limit", device.DeviceNo), 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)
	})

	t.Run("无权限设置其他店铺设备的限速", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺10",
			ShopCode: "SHOP_010",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000006",
			DeviceName:  "测试设备6",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_3",
			Phone:    "13800000203",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		body := []byte(`{"uploadSpeed": 1024, "downloadSpeed": 2048}`)
		resp, err := env.AsUser(agentAccount).Request("PUT", fmt.Sprintf("/api/admin/devices/by-imei/%s/speed-limit", device.DeviceNo), body)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_SetWiFi 测试设置WiFi接口
func TestGatewayDevice_SetWiFi(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000007",
		DeviceName:  "测试设备7",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功设置WiFi", func(t *testing.T) {
		body := []byte(`{"ssid": "TestWiFi", "password": "password123", "enabled": 1}`)
		resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/devices/by-imei/%s/wifi", device.DeviceNo), 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)
	})

	t.Run("无权限设置其他店铺设备的WiFi", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺11",
			ShopCode: "SHOP_011",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000008",
			DeviceName:  "测试设备8",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_4",
			Phone:    "13800000204",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		body := []byte(`{"ssid": "TestWiFi", "password": "password123", "enabled": 1}`)
		resp, err := env.AsUser(agentAccount).Request("PUT", fmt.Sprintf("/api/admin/devices/by-imei/%s/wifi", device.DeviceNo), body)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_SwitchCard 测试切卡接口
func TestGatewayDevice_SwitchCard(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000009",
		DeviceName:  "测试设备9",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功切卡", func(t *testing.T) {
		body := []byte(`{"targetIccid": "89860001234567890013"}`)
		resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/switch-card", device.DeviceNo), 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)
	})

	t.Run("无权限切换其他店铺设备的卡", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺12",
			ShopCode: "SHOP_012",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000010",
			DeviceName:  "测试设备10",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_5",
			Phone:    "13800000205",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		body := []byte(`{"targetIccid": "89860001234567890013"}`)
		resp, err := env.AsUser(agentAccount).Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/switch-card", device.DeviceNo), body)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_RebootDevice 测试重启设备接口
func TestGatewayDevice_RebootDevice(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000011",
		DeviceName:  "测试设备11",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功重启设备", func(t *testing.T) {
		resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/reboot", device.DeviceNo), 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)
	})

	t.Run("无权限重启其他店铺的设备", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺13",
			ShopCode: "SHOP_013",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000012",
			DeviceName:  "测试设备12",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_6",
			Phone:    "13800000206",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		resp, err := env.AsUser(agentAccount).Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/reboot", device.DeviceNo), nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}

// TestGatewayDevice_ResetDevice 测试恢复出厂接口
func TestGatewayDevice_ResetDevice(t *testing.T) {
	env := integ.NewIntegrationTestEnv(t)

	device := &model.Device{
		DeviceNo:    "86000000000000000013",
		DeviceName:  "测试设备13",
		DeviceType:  "router",
		MaxSimSlots: 4,
		Status:      constants.DeviceStatusInStock,
	}
	require.NoError(t, env.TX.Create(device).Error)

	t.Run("成功恢复出厂", func(t *testing.T) {
		resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/reset", device.DeviceNo), 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)
	})

	t.Run("无权限恢复其他店铺设备的出厂设置", func(t *testing.T) {
		shop2 := &model.Shop{
			ShopName: "测试店铺14",
			ShopCode: "SHOP_014",
			Level:    1,
		}
		require.NoError(t, env.TX.Create(shop2).Error)

		device2 := &model.Device{
			DeviceNo:    "86000000000000000014",
			DeviceName:  "测试设备14",
			DeviceType:  "router",
			MaxSimSlots: 4,
			Status:      constants.DeviceStatusInStock,
			ShopID:      &shop2.ID,
		}
		require.NoError(t, env.TX.Create(device2).Error)

		agentAccount := &model.Account{
			Username: "agent_test_device_gateway_7",
			Phone:    "13800000207",
			UserType: constants.UserTypeAgent,
			ShopID:   &shop2.ID,
			Status:   1,
		}
		require.NoError(t, env.TX.Create(agentAccount).Error)

		resp, err := env.AsUser(agentAccount).Request("POST", fmt.Sprintf("/api/admin/devices/by-imei/%s/reset", device.DeviceNo), nil)
		require.NoError(t, err)
		defer resp.Body.Close()

		assert.Equal(t, 404, resp.StatusCode)
	})
}
