package com.zhengmeng.ocrplatform.settings;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AppSettingService {
    private final AppSettingRepository repository;

    public AppSettingService(AppSettingRepository repository) {
        this.repository = repository;
    }

    @Transactional(readOnly = true)
    public List<AppSettingItem> listSettings() {
        return repository.findAllByOrderByKeyAsc().stream()
                .map(AppSettingItem::fromEntity)
                .toList();
    }

    @Transactional
    public List<AppSettingItem> updateSettings(AppSettingUpdateRequest request) {
        Map<String, AppSettingEntity> existing = repository.findAll().stream()
                .collect(Collectors.toMap(AppSettingEntity::getKey, Function.identity()));
        LocalDateTime now = LocalDateTime.now();
        for (AppSettingValueUpdate item : request.items()) {
            AppSettingEntity entity = existing.get(item.key());
            if (entity == null) {
                throw new IllegalArgumentException("Unknown setting key: " + item.key());
            }
            entity.setValue(normalizeValue(entity, item.value()));
            entity.setUpdatedAt(now);
            repository.save(entity);
        }
        return listSettings();
    }

    @Transactional
    public List<AppSettingItem> resetSettings() {
        LocalDateTime now = LocalDateTime.now();
        repository.findAll().forEach(entity -> {
            entity.setValue(entity.getDefaultValue());
            entity.setUpdatedAt(now);
            repository.save(entity);
        });
        return listSettings();
    }

    private String normalizeValue(AppSettingEntity entity, String rawValue) {
        String value = rawValue == null ? "" : rawValue.trim();
        return switch (entity.getType()) {
            case "number" -> {
                if (!value.matches("^-?\\d+(\\.\\d+)?$")) {
                    throw new IllegalArgumentException(entity.getKey() + " must be a number");
                }
                yield value;
            }
            case "switch" -> Boolean.toString(Boolean.parseBoolean(value));
            default -> value;
        };
    }
}
