package auth

import (
	"testing"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/stretchr/testify/assert"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

func TestClassifyPermissions_PlatformFilter(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	service := &Service{logger: logger}

	permissions := []*model.Permission{
		{
			Model:    gorm.Model{ID: 1},
			PermCode: "dashboard:menu",
			PermName: "仪表盘",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 2},
			PermCode: "user:menu",
			PermName: "用户管理",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformWeb,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 3},
			PermCode: "mobile:menu",
			PermName: "移动端菜单",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformH5,
			Status:   constants.StatusEnabled,
		},
	}

	allCodes, menus, buttons, err := service.classifyPermissions(permissions, constants.PlatformWeb)

	assert.NoError(t, err)
	assert.Len(t, allCodes, 2)
	assert.Contains(t, allCodes, "dashboard:menu")
	assert.Contains(t, allCodes, "user:menu")
	assert.NotContains(t, allCodes, "mobile:menu")
	assert.Len(t, menus, 2)
	assert.Empty(t, buttons)
}

func TestClassifyPermissions_MenuAndButton(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	service := &Service{logger: logger}

	permissions := []*model.Permission{
		{
			Model:    gorm.Model{ID: 1},
			PermCode: "user:menu",
			PermName: "用户管理",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 2},
			PermCode: "user:create",
			PermName: "创建用户",
			PermType: constants.PermissionTypeButton,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 3},
			PermCode: "user:delete",
			PermName: "删除用户",
			PermType: constants.PermissionTypeButton,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
	}

	allCodes, menus, buttons, err := service.classifyPermissions(permissions, constants.PlatformWeb)

	assert.NoError(t, err)
	assert.Len(t, allCodes, 3)
	assert.Len(t, menus, 1)
	assert.Equal(t, "user:menu", menus[0].PermCode)
	assert.Len(t, buttons, 2)
	assert.Contains(t, buttons, "user:create")
	assert.Contains(t, buttons, "user:delete")
}

func TestClassifyPermissions_AllPermissions(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	service := &Service{logger: logger}

	permissions := []*model.Permission{
		{
			Model:    gorm.Model{ID: 1},
			PermCode: "menu1",
			PermName: "菜单1",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 2},
			PermCode: "button1",
			PermName: "按钮1",
			PermType: constants.PermissionTypeButton,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
	}

	allCodes, _, _, err := service.classifyPermissions(permissions, constants.PlatformWeb)

	assert.NoError(t, err)
	assert.Len(t, allCodes, 2)
	assert.Contains(t, allCodes, "menu1")
	assert.Contains(t, allCodes, "button1")
}

func TestClassifyPermissions_PlatformAll(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	service := &Service{logger: logger}

	permissions := []*model.Permission{
		{
			Model:    gorm.Model{ID: 1},
			PermCode: "common:menu",
			PermName: "通用菜单",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
	}

	allCodesWeb, menusWeb, _, errWeb := service.classifyPermissions(permissions, constants.PlatformWeb)
	allCodesH5, menusH5, _, errH5 := service.classifyPermissions(permissions, constants.PlatformH5)

	assert.NoError(t, errWeb)
	assert.NoError(t, errH5)
	assert.Len(t, allCodesWeb, 1)
	assert.Len(t, allCodesH5, 1)
	assert.Len(t, menusWeb, 1)
	assert.Len(t, menusH5, 1)
	assert.Equal(t, "common:menu", menusWeb[0].PermCode)
	assert.Equal(t, "common:menu", menusH5[0].PermCode)
}

func TestClassifyPermissions_DisabledPermissions(t *testing.T) {
	logger, _ := zap.NewDevelopment()
	service := &Service{logger: logger}

	permissions := []*model.Permission{
		{
			Model:    gorm.Model{ID: 1},
			PermCode: "enabled:menu",
			PermName: "启用菜单",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusEnabled,
		},
		{
			Model:    gorm.Model{ID: 2},
			PermCode: "disabled:menu",
			PermName: "禁用菜单",
			PermType: constants.PermissionTypeMenu,
			Platform: constants.PlatformAll,
			Status:   constants.StatusDisabled,
		},
	}

	allCodes, menus, _, err := service.classifyPermissions(permissions, constants.PlatformWeb)

	assert.NoError(t, err)
	assert.Len(t, allCodes, 1)
	assert.Contains(t, allCodes, "enabled:menu")
	assert.NotContains(t, allCodes, "disabled:menu")
	assert.Len(t, menus, 1)
}
