package cn.novalon.manage.sys.core.service.impl;

import cn.novalon.manage.sys.core.domain.Dictionary;
import cn.novalon.manage.sys.core.exception.DictionaryAlreadyExistsException;
import cn.novalon.manage.sys.core.repository.IDictionaryRepository;
import cn.novalon.manage.sys.core.service.IDictionaryService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;

/**
 * 字典服务实现类
 * 
 * @author 张翔
 * @date 2026-03-14
 */
@Service
public class DictionaryService implements IDictionaryService {

    private final IDictionaryRepository repository;

    public DictionaryService(IDictionaryRepository repository) {
        this.repository = repository;
    }

    @Override
    public Flux<Dictionary> findAll() {
        return repository.findAll();
    }

    @Override
    public Mono<Dictionary> findById(Long id) {
        return repository.findById(id);
    }

    @Override
    public Flux<Dictionary> findByType(String type) {
        return repository.findByType(type);
    }

    @Override
    public Mono<Boolean> checkTypeAndCodeExists(String type, String code) {
        return repository.existsByTypeAndCode(type, code);
    }

    @Override
    public Mono<Dictionary> save(Dictionary dictionary) {
        if (dictionary.getId() == null) {
            dictionary.setCreatedAt(LocalDateTime.now());
            return checkTypeAndCodeExists(dictionary.getType(), dictionary.getCode())
                    .flatMap(exists -> {
                        if (exists) {
                            return Mono.error(new DictionaryAlreadyExistsException(dictionary.getType(), dictionary.getCode()));
                        }
                        dictionary.setUpdatedAt(LocalDateTime.now());
                        return repository.save(dictionary);
                    });
        }
        dictionary.setUpdatedAt(LocalDateTime.now());
        return repository.save(dictionary);
    }

    @Override
    public Mono<Dictionary> update(Long id, Dictionary dictionary) {
        return repository.findById(id)
                .flatMap(existing -> {
                    if (dictionary.getName() != null) {
                        existing.setName(dictionary.getName());
                    }
                    if (dictionary.getValue() != null) {
                        existing.setValue(dictionary.getValue());
                    }
                    if (dictionary.getRemark() != null) {
                        existing.setRemark(dictionary.getRemark());
                    }
                    if (dictionary.getSort() != null) {
                        existing.setSort(dictionary.getSort());
                    }
                    existing.setUpdatedAt(LocalDateTime.now());
                    return repository.save(existing);
                });
    }

    @Override
    public Mono<Void> deleteById(Long id) {
        return repository.deleteById(id);
    }
}
