package adminuser

import (
	"errors"
	"strings"
	"testing"

	"hfb_sys/backend/internal/model"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

func TestDepositFreeQuotaAmountCent(t *testing.T) {
	tests := []struct {
		name string
		req  DepositFreeQuotaRequest
		want int64
	}{
		{
			name: "使用分字段",
			req:  DepositFreeQuotaRequest{AmountCent: 1234},
			want: 1234,
		},
		{
			name: "负分拒绝",
			req:  DepositFreeQuotaRequest{AmountCent: -1},
			want: -1,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := depositFreeQuotaAmountCent(tt.req); got != tt.want {
				t.Fatalf("depositFreeQuotaAmountCent() = %d, want %d", got, tt.want)
			}
		})
	}
}

func TestParseBoolQuery(t *testing.T) {
	tests := []struct {
		name  string
		value string
		want  bool
	}{
		{name: "true 开启", value: "true", want: true},
		{name: "数字 1 开启", value: "1", want: true},
		{name: "on 开启", value: "on", want: true},
		{name: "空值关闭", value: "", want: false},
		{name: "false 关闭", value: "false", want: false},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := parseBoolQuery(tt.value); got != tt.want {
				t.Fatalf("parseBoolQuery(%q) = %v, want %v", tt.value, got, tt.want)
			}
		})
	}
}

func TestApplyUserFilterHasDepositFreeQuota(t *testing.T) {
	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{DryRun: true})
	if err != nil {
		t.Fatalf("打开测试数据库失败：%v", err)
	}

	stmt := applyUserFilter(db.Table("users AS u"), ListQuery{
		Status:              "active",
		HasDepositFreeQuota: true,
	}).Find(&[]struct{}{}).Statement
	sql := stmt.SQL.String()

	if !strings.Contains(sql, "u.deposit_free_quota_cent > 0") {
		t.Fatalf("SQL 未包含免押额度过滤：%s", sql)
	}
	if len(stmt.Vars) != 1 || stmt.Vars[0] != "active" {
		t.Fatalf("筛选变量不正确：%v", stmt.Vars)
	}
}

func TestManualRealnameUpdatesUserRecordAndAudit(t *testing.T) {
	db := setupAdminUserTestDB(t)
	user := model.User{
		Phone:          "13900000001",
		Nickname:       "待实名用户",
		RealnameStatus: "rejected",
		Status:         "active",
	}
	if err := db.Create(&user).Error; err != nil {
		t.Fatalf("创建用户失败：%v", err)
	}

	repo := NewRepository(db)
	got, err := repo.ManualRealname(t.Context(), 99, user.ID, ManualRealnameRequest{
		Name:   "周奕男",
		IDNo:   "130682200604080615",
		Reason: "第三方服务异常，客服人工核验通过",
	}, AuditMeta{IP: "127.0.0.1", UserAgent: "test", RequestID: "req-1"})
	if err != nil {
		t.Fatalf("ManualRealname() error = %v", err)
	}
	if got.RealnameStatus != "verified" {
		t.Fatalf("用户实名状态 = %s, want verified", got.RealnameStatus)
	}

	var savedUser model.User
	if err := db.First(&savedUser, user.ID).Error; err != nil {
		t.Fatalf("查询用户失败：%v", err)
	}
	if savedUser.RealnameStatus != "verified" {
		t.Fatalf("数据库用户实名状态 = %s, want verified", savedUser.RealnameStatus)
	}

	var record model.UserRealname
	if err := db.Where("user_id = ?", user.ID).First(&record).Error; err != nil {
		t.Fatalf("查询实名记录失败：%v", err)
	}
	if record.Provider != "admin_manual" || record.Status != "verified" {
		t.Fatalf("实名记录不正确：provider=%s status=%s", record.Provider, record.Status)
	}
	if record.MaskedName != "周**" || record.MaskedIDNo != "1306**********0615" {
		t.Fatalf("脱敏信息不正确：name=%s id=%s", record.MaskedName, record.MaskedIDNo)
	}
	if record.EncryptedName != "周奕男" || record.EncryptedIDNo != "130682200604080615" {
		t.Fatalf("加密字段未写入：name=%s id=%s", record.EncryptedName, record.EncryptedIDNo)
	}
	if record.VerifiedAt == nil {
		t.Fatal("VerifiedAt 不能为空")
	}

	var audit model.AuditLog
	if err := db.Where("action = ?", "admin_user.manual_realname").First(&audit).Error; err != nil {
		t.Fatalf("查询审计日志失败：%v", err)
	}
	if audit.ActorID != 99 || audit.BizID == nil || *audit.BizID != user.ID {
		t.Fatalf("审计日志主体不正确：actor=%d biz=%v", audit.ActorID, audit.BizID)
	}
	if strings.Contains(string(audit.Detail), "130682200604080615") {
		t.Fatalf("审计日志不应包含完整身份证号：%s", string(audit.Detail))
	}
}

func TestManualRealnameRejectsVerifiedUser(t *testing.T) {
	db := setupAdminUserTestDB(t)
	user := model.User{
		Phone:          "13900000002",
		Nickname:       "已实名用户",
		RealnameStatus: "verified",
		Status:         "active",
	}
	if err := db.Create(&user).Error; err != nil {
		t.Fatalf("创建用户失败：%v", err)
	}

	repo := NewRepository(db)
	_, err := repo.ManualRealname(t.Context(), 99, user.ID, ManualRealnameRequest{
		Name: "周奕男",
		IDNo: "130682200604080615",
	}, AuditMeta{})
	if !errors.Is(err, ErrRealnameAlreadyVerified) {
		t.Fatalf("ManualRealname() error = %v, want ErrRealnameAlreadyVerified", err)
	}
}

func setupAdminUserTestDB(t *testing.T) *gorm.DB {
	t.Helper()
	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
	if err != nil {
		t.Fatalf("打开测试数据库失败：%v", err)
	}
	if err := db.AutoMigrate(
		&model.User{},
		&model.UserRealname{},
		&model.AuditLog{},
		&model.RentalOrder{},
		&model.RentalListing{},
		&model.Dispute{},
	); err != nil {
		t.Fatalf("数据库迁移失败：%v", err)
	}
	return db
}
