package com.ga.common.system;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.common.util.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class SystemConfigService {

    private final SystemConfigMapper mapper;

    public List<SystemConfigVO> listAll() {
        return mapper.selectAll();
    }

    public List<SystemConfigVO> listByGroup(String group) {
        return mapper.selectByGroup(group);
    }

    @Cacheable(value = "systemConfig", key = "#key")
    public Optional<String> getValue(String key) {
        SystemConfigVO vo = mapper.selectByKey(key);
        return Optional.ofNullable(vo).map(SystemConfigVO::getConfigValue);
    }

    public String getString(String key, String defaultValue) {
        return getValue(key).orElse(defaultValue);
    }

    public int getInt(String key, int defaultValue) {
        return getValue(key).map(Integer::parseInt).orElse(defaultValue);
    }

    public BigDecimal getDecimal(String key, BigDecimal defaultValue) {
        return getValue(key).map(BigDecimal::new).orElse(defaultValue);
    }

    public boolean getBoolean(String key, boolean defaultValue) {
        return getValue(key).map(s -> "true".equalsIgnoreCase(s) || "Y".equalsIgnoreCase(s)).orElse(defaultValue);
    }

    @Transactional
    @CacheEvict(value = "systemConfig", key = "#vo.configKey")
    public void update(SystemConfigVO vo) {
        SystemConfigVO existing = mapper.selectByKey(vo.getConfigKey());
        if (existing == null) throw new BizException(ErrorCode.NOT_FOUND);
        if (!"Y".equals(existing.getIsEditable())) {
            throw new BizException(ErrorCode.NOT_PERMITTED, "수정할 수 없는 설정입니다");
        }
        vo.setUpdatedAt(LocalDateTime.now());
        vo.setUpdatedBy(SecurityUtil.getCurrentUserId());
        mapper.update(vo);
    }
}
