package adminaudit

import (
	"time"

	"hfb_sys/backend/internal/model"

	"gorm.io/datatypes"
	"gorm.io/gorm"
)

type Repository struct {
	db *gorm.DB
}

func NewRepository(db *gorm.DB) *Repository {
	return &Repository{db: db}
}

func (r *Repository) List(query Query) (*PaginatedResult, error) {
	db := r.db.Table("audit_logs AS al").
		Select(`al.id, al.actor_type, al.actor_id, COALESCE(au.username, '') AS actor_username,
			COALESCE(au.nickname, '') AS actor_nickname, al.action, al.biz_type, al.biz_id,
			al.ip, al.user_agent, al.detail, al.created_at`).
		Joins("LEFT JOIN admin_users AS au ON au.id = al.actor_id AND al.actor_type = ?", "admin")

	countDB := r.db.Model(&model.AuditLog{})
	if query.ActorID > 0 {
		db = db.Where("al.actor_id = ?", query.ActorID)
		countDB = countDB.Where("actor_id = ?", query.ActorID)
	}
	if query.Action != "" {
		db = db.Where("al.action = ?", query.Action)
		countDB = countDB.Where("action = ?", query.Action)
	}
	if query.BizType != "" {
		db = db.Where("al.biz_type = ?", query.BizType)
		countDB = countDB.Where("biz_type = ?", query.BizType)
	}

	var total int64
	if err := countDB.Count(&total).Error; err != nil {
		return nil, err
	}

	offset := (query.Page - 1) * query.PageSize
	var rows []auditLogRow
	if err := db.Order("al.id DESC").Offset(offset).Limit(query.PageSize).Scan(&rows).Error; err != nil {
		return nil, err
	}
	items := make([]LogDTO, 0, len(rows))
	for _, row := range rows {
		items = append(items, row.toDTO())
	}
	return &PaginatedResult{Items: items, Total: total, Page: query.Page, PageSize: query.PageSize}, nil
}

type auditLogRow struct {
	ID            uint64
	ActorType     string
	ActorID       uint64
	ActorUsername string
	ActorNickname string
	Action        string
	BizType       string
	BizID         *uint64
	IP            string
	UserAgent     string
	Detail        datatypes.JSON
	CreatedAt     time.Time
}

func (row auditLogRow) toDTO() LogDTO {
	return LogDTO{
		ID:            row.ID,
		ActorType:     row.ActorType,
		ActorID:       row.ActorID,
		ActorUsername: row.ActorUsername,
		ActorNickname: row.ActorNickname,
		Action:        row.Action,
		BizType:       row.BizType,
		BizID:         row.BizID,
		IP:            row.IP,
		UserAgent:     row.UserAgent,
		Detail:        row.Detail,
		CreatedAt:     row.CreatedAt,
	}
}
