package service

import (
	"context"
	"errors"
	"fmt"
	"strconv"
	"time"

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

// CustomFieldService 自定义字段服务
type CustomFieldService struct {
	fieldRepo *repository.CustomFieldRepository
	valueRepo *repository.UserCustomFieldValueRepository
}

// NewCustomFieldService 创建自定义字段服务
func NewCustomFieldService(
	fieldRepo *repository.CustomFieldRepository,
	valueRepo *repository.UserCustomFieldValueRepository,
) *CustomFieldService {
	return &CustomFieldService{
		fieldRepo: fieldRepo,
		valueRepo: valueRepo,
	}
}

// CreateFieldRequest 创建字段请求
type CreateFieldRequest struct {
	Name     string  `json:"name" binding:"required"`
	FieldKey string  `json:"field_key" binding:"required"`
	Type     int     `json:"type" binding:"required"`
	Required bool    `json:"required"`
	Default  string  `json:"default"`
	MinLen   int     `json:"min_len"`
	MaxLen   int     `json:"max_len"`
	MinVal   float64 `json:"min_val"`
	MaxVal   float64 `json:"max_val"`
	Options  string  `json:"options"`
	Sort     int     `json:"sort"`
}

// UpdateFieldRequest 更新字段请求
type UpdateFieldRequest struct {
	Name     string  `json:"name"`
	Type     int     `json:"type"`
	Required *bool   `json:"required"`
	Default  string  `json:"default"`
	MinLen   int     `json:"min_len"`
	MaxLen   int     `json:"max_len"`
	MinVal   float64 `json:"min_val"`
	MaxVal   float64 `json:"max_val"`
	Options  string  `json:"options"`
	Sort     int     `json:"sort"`
	Status   *int    `json:"status"`
}

// CreateField 创建自定义字段
func (s *CustomFieldService) CreateField(ctx context.Context, req *CreateFieldRequest) (*domain.CustomField, error) {
	// 检查field_key是否已存在
	existing, err := s.fieldRepo.GetByFieldKey(ctx, req.FieldKey)
	if err == nil && existing != nil {
		return nil, errors.New("字段标识符已存在")
	}

	field := &domain.CustomField{
		Name:       req.Name,
		FieldKey:   req.FieldKey,
		Type:       domain.CustomFieldType(req.Type),
		Required:   req.Required,
		DefaultVal: req.Default,
		MinLen:     req.MinLen,
		MaxLen:     req.MaxLen,
		MinVal:     req.MinVal,
		MaxVal:     req.MaxVal,
		Options:    req.Options,
		Sort:       req.Sort,
		Status:     1,
	}

	if err := s.fieldRepo.Create(ctx, field); err != nil {
		return nil, err
	}

	return field, nil
}

// UpdateField 更新自定义字段
func (s *CustomFieldService) UpdateField(ctx context.Context, id int64, req *UpdateFieldRequest) (*domain.CustomField, error) {
	field, err := s.fieldRepo.GetByID(ctx, id)
	if err != nil {
		return nil, errors.New("字段不存在")
	}

	if req.Name != "" {
		field.Name = req.Name
	}
	if req.Type > 0 {
		field.Type = domain.CustomFieldType(req.Type)
	}
	if req.Required != nil {
		field.Required = *req.Required
	}
	if req.Default != "" {
		field.DefaultVal = req.Default
	}
	if req.MinLen > 0 {
		field.MinLen = req.MinLen
	}
	if req.MaxLen > 0 {
		field.MaxLen = req.MaxLen
	}
	if req.MinVal > 0 {
		field.MinVal = req.MinVal
	}
	if req.MaxVal > 0 {
		field.MaxVal = req.MaxVal
	}
	if req.Options != "" {
		field.Options = req.Options
	}
	if req.Sort > 0 {
		field.Sort = req.Sort
	}
	if req.Status != nil {
		field.Status = *req.Status
	}

	if err := s.fieldRepo.Update(ctx, field); err != nil {
		return nil, err
	}

	return field, nil
}

// DeleteField 删除自定义字段
func (s *CustomFieldService) DeleteField(ctx context.Context, id int64) error {
	field, err := s.fieldRepo.GetByID(ctx, id)
	if err != nil {
		return errors.New("字段不存在")
	}

	// 删除字段定义
	if err := s.fieldRepo.Delete(ctx, id); err != nil {
		return err
	}

	// 清理用户的该字段值（可选，取决于业务需求）
	_ = field

	return nil
}

// GetField 获取自定义字段
func (s *CustomFieldService) GetField(ctx context.Context, id int64) (*domain.CustomField, error) {
	return s.fieldRepo.GetByID(ctx, id)
}

// ListFields 获取所有启用的自定义字段
func (s *CustomFieldService) ListFields(ctx context.Context) ([]*domain.CustomField, error) {
	return s.fieldRepo.List(ctx)
}

// ListAllFields 获取所有自定义字段
func (s *CustomFieldService) ListAllFields(ctx context.Context) ([]*domain.CustomField, error) {
	return s.fieldRepo.ListAll(ctx)
}

// SetUserFieldValue 设置用户的自定义字段值
func (s *CustomFieldService) SetUserFieldValue(ctx context.Context, userID int64, fieldKey string, value string) error {
	// 获取字段定义
	field, err := s.fieldRepo.GetByFieldKey(ctx, fieldKey)
	if err != nil {
		return errors.New("字段不存在")
	}

	// 验证值
	if err := s.validateFieldValue(field, value); err != nil {
		return err
	}

	return s.valueRepo.Set(ctx, userID, field.ID, fieldKey, value)
}

// BatchSetUserFieldValues 批量设置用户的自定义字段值
func (s *CustomFieldService) BatchSetUserFieldValues(ctx context.Context, userID int64, values map[string]string) error {
	// 获取所有启用的字段定义
	fields, err := s.fieldRepo.List(ctx)
	if err != nil {
		return err
	}

	fieldMap := make(map[string]*domain.CustomField)
	for _, f := range fields {
		fieldMap[f.FieldKey] = f
	}

	// 验证每个值
	for fieldKey, value := range values {
		field, ok := fieldMap[fieldKey]
		if !ok {
			return fmt.Errorf("字段不存在: %s", fieldKey)
		}
		if err := s.validateFieldValue(field, value); err != nil {
			return err
		}
	}

	// 批量设置值
	return s.valueRepo.BatchSet(ctx, userID, values)
}

// GetUserFieldValues 获取用户的所有自定义字段值
func (s *CustomFieldService) GetUserFieldValues(ctx context.Context, userID int64) ([]*domain.CustomFieldValueResponse, error) {
	// 获取所有启用的字段定义
	fields, err := s.fieldRepo.List(ctx)
	if err != nil {
		return nil, err
	}

	// 获取用户的字段值
	values, err := s.valueRepo.GetByUserID(ctx, userID)
	if err != nil {
		return nil, err
	}

	// 构建字段值映射
	valueMap := make(map[int64]*domain.UserCustomFieldValue)
	for _, v := range values {
		valueMap[v.FieldID] = v
	}

	// 构建响应
	fieldMap := make(map[string]*domain.CustomField)
	for _, f := range fields {
		fieldMap[f.FieldKey] = f
	}

	var result []*domain.CustomFieldValueResponse
	for _, field := range fields {
		resp := &domain.CustomFieldValueResponse{
			FieldKey: field.FieldKey,
		}

		if val, ok := valueMap[field.ID]; ok {
			resp.Value = val.GetValueAsInterface(field)
		} else if field.DefaultVal != "" {
			resp.Value = field.DefaultVal
		} else {
			resp.Value = nil
		}

		result = append(result, resp)
	}

	return result, nil
}

// DeleteUserFieldValue 删除用户的自定义字段值
func (s *CustomFieldService) DeleteUserFieldValue(ctx context.Context, userID int64, fieldKey string) error {
	field, err := s.fieldRepo.GetByFieldKey(ctx, fieldKey)
	if err != nil {
		return errors.New("字段不存在")
	}

	return s.valueRepo.Delete(ctx, userID, field.ID)
}

// validateFieldValue 验证字段值
func (s *CustomFieldService) validateFieldValue(field *domain.CustomField, value string) error {
	// 检查必填
	if field.Required && value == "" {
		return errors.New("字段值不能为空")
	}

	// 如果值为空且有默认值，跳过验证
	if value == "" && field.DefaultVal != "" {
		return nil
	}

	switch field.Type {
	case domain.CustomFieldTypeString:
		// 字符串长度验证
		if field.MinLen > 0 && len(value) < field.MinLen {
			return fmt.Errorf("值长度不能小于%d", field.MinLen)
		}
		if field.MaxLen > 0 && len(value) > field.MaxLen {
			return fmt.Errorf("值长度不能大于%d", field.MaxLen)
		}
	case domain.CustomFieldTypeNumber:
		// 数字验证
		numVal, err := strconv.ParseFloat(value, 64)
		if err != nil {
			return errors.New("值必须是数字")
		}
		if field.MinVal > 0 && numVal < field.MinVal {
			return fmt.Errorf("值不能小于%.2f", field.MinVal)
		}
		if field.MaxVal > 0 && numVal > field.MaxVal {
			return fmt.Errorf("值不能大于%.2f", field.MaxVal)
		}
	case domain.CustomFieldTypeBoolean:
		// 布尔验证
		if value != "true" && value != "false" && value != "1" && value != "0" {
			return errors.New("值必须是布尔值(true/false/1/0)")
		}
	case domain.CustomFieldTypeDate:
		// 日期验证
		_, err := time.Parse("2006-01-02", value)
		if err != nil {
			return errors.New("值必须是有效的日期格式(YYYY-MM-DD)")
		}
	}

	return nil
}
