package repository

import (
	"context"

	"gorm.io/gorm"

	"github.com/user-management-system/internal/domain"
)

// CustomFieldRepository 自定义字段数据访问层
type CustomFieldRepository struct {
	db *gorm.DB
}

// NewCustomFieldRepository 创建自定义字段数据访问层
func NewCustomFieldRepository(db *gorm.DB) *CustomFieldRepository {
	return &CustomFieldRepository{db: db}
}

// Create 创建自定义字段
func (r *CustomFieldRepository) Create(ctx context.Context, field *domain.CustomField) error {
	return r.db.WithContext(ctx).Create(field).Error
}

// Update 更新自定义字段
func (r *CustomFieldRepository) Update(ctx context.Context, field *domain.CustomField) error {
	return r.db.WithContext(ctx).Save(field).Error
}

// Delete 删除自定义字段
func (r *CustomFieldRepository) Delete(ctx context.Context, id int64) error {
	return r.db.WithContext(ctx).Delete(&domain.CustomField{}, id).Error
}

// GetByID 根据ID获取自定义字段
func (r *CustomFieldRepository) GetByID(ctx context.Context, id int64) (*domain.CustomField, error) {
	var field domain.CustomField
	err := r.db.WithContext(ctx).First(&field, id).Error
	if err != nil {
		return nil, err
	}
	return &field, nil
}

// GetByFieldKey 根据FieldKey获取自定义字段
func (r *CustomFieldRepository) GetByFieldKey(ctx context.Context, fieldKey string) (*domain.CustomField, error) {
	var field domain.CustomField
	err := r.db.WithContext(ctx).Where("field_key = ?", fieldKey).First(&field).Error
	if err != nil {
		return nil, err
	}
	return &field, nil
}

// List 获取所有启用的自定义字段
func (r *CustomFieldRepository) List(ctx context.Context) ([]*domain.CustomField, error) {
	var fields []*domain.CustomField
	err := r.db.WithContext(ctx).Where("status = ?", 1).Order("sort ASC").Find(&fields).Error
	if err != nil {
		return nil, err
	}
	return fields, nil
}

// ListAll 获取所有自定义字段
func (r *CustomFieldRepository) ListAll(ctx context.Context) ([]*domain.CustomField, error) {
	var fields []*domain.CustomField
	err := r.db.WithContext(ctx).Order("sort ASC").Find(&fields).Error
	if err != nil {
		return nil, err
	}
	return fields, nil
}

// UserCustomFieldValueRepository 用户自定义字段值数据访问层
type UserCustomFieldValueRepository struct {
	db *gorm.DB
}

// NewUserCustomFieldValueRepository 创建用户自定义字段值数据访问层
func NewUserCustomFieldValueRepository(db *gorm.DB) *UserCustomFieldValueRepository {
	return &UserCustomFieldValueRepository{db: db}
}

// Set 为用户设置自定义字段值（upsert）
func (r *UserCustomFieldValueRepository) Set(ctx context.Context, userID int64, fieldID int64, fieldKey, value string) error {
	return r.db.WithContext(ctx).Exec(`
		INSERT INTO user_custom_field_values (user_id, field_id, field_key, value, created_at, updated_at)
		VALUES (?, ?, ?, ?, NOW(), NOW())
		ON CONFLICT(user_id, field_id) DO UPDATE SET value = ?, updated_at = NOW()
	`, userID, fieldID, fieldKey, value, value).Error
}

// GetByUserID 获取用户的所有自定义字段值
func (r *UserCustomFieldValueRepository) GetByUserID(ctx context.Context, userID int64) ([]*domain.UserCustomFieldValue, error) {
	var values []*domain.UserCustomFieldValue
	err := r.db.WithContext(ctx).Where("user_id = ?", userID).Find(&values).Error
	if err != nil {
		return nil, err
	}
	return values, nil
}

// GetByUserIDAndFieldKey 获取用户指定字段的值
func (r *UserCustomFieldValueRepository) GetByUserIDAndFieldKey(ctx context.Context, userID int64, fieldKey string) (*domain.UserCustomFieldValue, error) {
	var value domain.UserCustomFieldValue
	err := r.db.WithContext(ctx).Where("user_id = ? AND field_key = ?", userID, fieldKey).First(&value).Error
	if err != nil {
		return nil, err
	}
	return &value, nil
}

// Delete 删除用户的自定义字段值
func (r *UserCustomFieldValueRepository) Delete(ctx context.Context, userID int64, fieldID int64) error {
	return r.db.WithContext(ctx).Where("user_id = ? AND field_id = ?", userID, fieldID).Delete(&domain.UserCustomFieldValue{}).Error
}

// DeleteByUserID 删除用户的所有自定义字段值
func (r *UserCustomFieldValueRepository) DeleteByUserID(ctx context.Context, userID int64) error {
	return r.db.WithContext(ctx).Where("user_id = ?", userID).Delete(&domain.UserCustomFieldValue{}).Error
}

// BatchSet 批量设置用户的自定义字段值
func (r *UserCustomFieldValueRepository) BatchSet(ctx context.Context, userID int64, values map[string]string) error {
	if len(values) == 0 {
		return nil
	}

	return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		for fieldKey, value := range values {
			if err := tx.Exec(`
				INSERT INTO user_custom_field_values (user_id, field_id, field_key, value, created_at, updated_at)
				VALUES (
					?,
					(SELECT id FROM custom_fields WHERE field_key = ? LIMIT 1),
					?,
					?,
					NOW(),
					NOW()
				)
				ON CONFLICT(user_id, field_id) DO UPDATE SET value = ?, updated_at = NOW()
			`, userID, fieldKey, fieldKey, value, value).Error; err != nil {
				return err
			}
		}
		return nil
	})
}
