package service

import (
	"licserver/internal/utils"
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestLicenseService_CreateLicenses(t *testing.T) {
	db := utils.TestDB(t)
	service := NewLicenseService(db)

	tests := []struct {
		name    string
		input   *LicenseCreateInput
		wantErr bool
	}{
		{
			name: "创建时间授权码",
			input: &LicenseCreateInput{
				LicenseType: "time",
				Duration:    30,
				Count:       5,
				Remark:      "test time license",
			},
			wantErr: false,
		},
		{
			name: "创建次数授权码",
			input: &LicenseCreateInput{
				LicenseType: "count",
				MaxUses:     100,
				Count:       3,
				Remark:      "test count license",
			},
			wantErr: false,
		},
		{
			name: "创建永久授权码",
			input: &LicenseCreateInput{
				LicenseType: "permanent",
				Count:       1,
				Remark:      "test permanent license",
			},
			wantErr: false,
		},
		{
			name: "无效的授权类型",
			input: &LicenseCreateInput{
				LicenseType: "invalid",
				Count:       1,
			},
			wantErr: true,
		},
		{
			name: "时间授权无有效期",
			input: &LicenseCreateInput{
				LicenseType: "time",
				Duration:    0,
				Count:       1,
			},
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			licenses, err := service.CreateLicenses(tt.input, 1)
			if tt.wantErr {
				assert.Error(t, err)
				return
			}

			assert.NoError(t, err)
			assert.Len(t, licenses, tt.input.Count)

			for _, license := range licenses {
				assert.Equal(t, tt.input.LicenseType, license.LicenseType)
				assert.Equal(t, "unused", license.Status)
				assert.Equal(t, tt.input.Remark, license.Remark)

				if tt.input.LicenseType == "time" {
					assert.Equal(t, tt.input.Duration, license.Duration)
				} else if tt.input.LicenseType == "count" {
					assert.Equal(t, tt.input.MaxUses, license.MaxUses)
				}
			}
		})
	}
}

func TestLicenseService_UseLicense(t *testing.T) {
	db := utils.TestDB(t)
	service := NewLicenseService(db)

	// 创建测试授权码
	input := &LicenseCreateInput{
		LicenseType: "time",
		Duration:    30,
		Count:       1,
		Remark:      "test",
	}

	licenses, err := service.CreateLicenses(input, 1)
	assert.NoError(t, err)
	assert.Len(t, licenses, 1)

	tests := []struct {
		name      string
		code      string
		deviceUID string
		ip        string
		wantErr   bool
	}{
		{
			name:      "正常使用授权码",
			code:      licenses[0].Code,
			deviceUID: "test-device-001",
			ip:        "127.0.0.1",
			wantErr:   false,
		},
		{
			name:      "使用不存在的授权码",
			code:      "invalid-code",
			deviceUID: "test-device-002",
			ip:        "127.0.0.1",
			wantErr:   true,
		},
		{
			name:      "重复使用授权码",
			code:      licenses[0].Code,
			deviceUID: "test-device-003",
			ip:        "127.0.0.1",
			wantErr:   true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			license, err := service.UseLicense(tt.code, tt.deviceUID, tt.ip)
			if tt.wantErr {
				assert.Error(t, err)
				return
			}

			assert.NoError(t, err)
			assert.Equal(t, "used", license.Status)
			assert.Equal(t, tt.deviceUID, license.UsedBy)
			assert.NotZero(t, license.UsedAt)
		})
	}
}
