package com.yimeng.okr.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yimeng.okr.entity.KpiConfig;
import com.yimeng.okr.entity.KpiTemplate;
import com.yimeng.okr.exception.BusinessException;
import com.yimeng.okr.mapper.KpiConfigMapper;
import com.yimeng.okr.mapper.KpiTemplateMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class KpiService {

    private final KpiTemplateMapper templateMapper;
    private final KpiConfigMapper configMapper;
    private final AuthorizationService authorizationService;

    // Templates

    public List<KpiTemplate> listTemplates() {
        return templateMapper.selectList(null);
    }

    public KpiTemplate createTemplate(KpiTemplate template) {
        templateMapper.insert(template);
        return template;
    }

    public void updateTemplate(KpiTemplate template) {
        templateMapper.updateById(template);
    }

    public void deleteTemplate(Long id) {
        templateMapper.deleteById(id);
    }

    // Personal KPI Config

    public KpiConfig getOrCreateConfig(Long periodId, Long userId) {
        KpiConfig config = configMapper.selectOne(
                new LambdaQueryWrapper<KpiConfig>()
                        .eq(KpiConfig::getPeriodId, periodId)
                        .eq(KpiConfig::getUserId, userId));
        if (config == null) {
            config = new KpiConfig();
            config.setPeriodId(periodId);
            config.setUserId(userId);
            config.setVersion(1);
        }
        return config;
    }

    @Transactional
    public KpiConfig saveConfig(KpiConfig config, Long actorId) {
        authorizationService.requireCanManageUserData(actorId, config.getUserId());
        KpiConfig existing = configMapper.selectOne(
                new LambdaQueryWrapper<KpiConfig>()
                        .eq(KpiConfig::getPeriodId, config.getPeriodId())
                        .eq(KpiConfig::getUserId, config.getUserId()));
        if (existing != null) {
            if (existing.getLockedAt() != null) {
                throw new BusinessException("KPI配置已锁定，不可修改");
            }
            config.setId(existing.getId());
            config.setVersion(existing.getVersion() + 1);
            configMapper.updateById(config);
        } else {
            config.setVersion(1);
            configMapper.insert(config);
        }
        return config;
    }

    public void lockConfig(Long configId, Long actorId) {
        KpiConfig config = configMapper.selectById(configId);
        if (config == null) throw new BusinessException(404, "KPI配置不存在");
        authorizationService.requireCanManageUserData(actorId, config.getUserId());
        config.setLockedAt(LocalDateTime.now());
        configMapper.updateById(config);
    }

    public KpiConfig getConfig(Long periodId, Long userId, Long actorId) {
        authorizationService.requireCanViewUserData(actorId, userId);
        return configMapper.selectOne(
                new LambdaQueryWrapper<KpiConfig>()
                        .eq(KpiConfig::getPeriodId, periodId)
                        .eq(KpiConfig::getUserId, userId));
    }

    public List<KpiConfig> getConfigsByPeriod(Long periodId, Long actorId) {
        if (!authorizationService.isHrOrAbove(actorId)) {
            throw new BusinessException(403, "无权限，需要HR管理员或以上权限");
        }
        return configMapper.selectList(
                new LambdaQueryWrapper<KpiConfig>().eq(KpiConfig::getPeriodId, periodId));
    }

    public KpiTemplate getTemplateByPosition(String position) {
        if (position == null || position.isEmpty()) return null;
        return templateMapper.selectOne(
                new LambdaQueryWrapper<KpiTemplate>().eq(KpiTemplate::getName, position));
    }
}
