package com.example.demo.service;

import com.example.demo.model.Dept;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 部门管理服务。
 * 使用内存假数据实现部门增删改查及树形结构维护。
 */
@Service
public class DeptService {

    /** 内存数据存储 */
    private final Map<Long, Dept> deptMap = new ConcurrentHashMap<>();

    private final AtomicLong idGenerator = new AtomicLong(50);

    /**
     * 新增部门。
     *
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     *
     * @param dept 部门信息
     * @return 创建后的部门
     */
    public Dept createDept(Dept dept) {
        long deptId = idGenerator.incrementAndGet();
        dept.setDeptId(deptId);
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        if (dept.getStatus() == null) {
            dept.setStatus(1);
        }
        if (dept.getParentId() == null) {
            dept.setParentId(0L);
        }
        deptMap.put(deptId, dept);
        return dept;
    }

    /**
     * 编辑部门。
     *
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     *
     * @param id   部门ID
     * @param dept 更新后的部门信息
     * @return 更新后的部门
     */
    public Dept updateDept(Long id, Dept dept) {
        Dept existing = deptMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("部门不存在，ID: " + id);
        }
        if (dept.getDeptName() != null) {
            existing.setDeptName(dept.getDeptName());
        }
        if (dept.getParentId() != null) {
            existing.setParentId(dept.getParentId());
        }
        if (dept.getSortOrder() != null) {
            existing.setSortOrder(dept.getSortOrder());
        }
        if (dept.getStatus() != null) {
            existing.setStatus(dept.getStatus());
        }
        existing.setUpdateTime(LocalDateTime.now());
        deptMap.put(id, existing);
        return existing;
    }

    /**
     * 删除部门。
     *
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     *
     * @param id 部门ID
     */
    public void deleteDept(Long id) {
        if (!deptMap.containsKey(id)) {
            throw new IllegalArgumentException("部门不存在，ID: " + id);
        }
        boolean hasChildren = deptMap.values().stream()
                .anyMatch(d -> Objects.equals(d.getParentId(), id));
        if (hasChildren) {
            throw new IllegalStateException("该部门下存在子部门，无法删除");
        }
        deptMap.remove(id);
    }

    /**
     * 根据ID查询部门。
     *
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     *
     * @param id 部门ID
     * @return 部门信息
     */
    public Dept getDept(Long id) {
        Dept dept = deptMap.get(id);
        if (dept == null) {
            throw new IllegalArgumentException("部门不存在，ID: " + id);
        }
        return dept;
    }

    /**
     * 获取部门树形结构列表。
     *
     * @requirement(name="部门管理", id="SRS-IMS_F-003")
     * 以树形结构返回所有部门数据。
     *
     * @return 部门树形列表
     */
    public List<Dept> getDeptTree() {
        List<Dept> allDepts = new ArrayList<>(deptMap.values());
        Map<Long, List<Dept>> parentMap = allDepts.stream()
                .filter(d -> d.getParentId() != null && d.getParentId() > 0)
                .collect(Collectors.groupingBy(Dept::getParentId));

        for (Dept dept : allDepts) {
            dept.setChildren(parentMap.getOrDefault(dept.getDeptId(), List.of()));
        }

        return allDepts.stream()
                .filter(d -> d.getParentId() == null || d.getParentId() == 0L)
                .sorted(Comparator.comparingInt(Dept::getSortOrder))
                .collect(Collectors.toList());
    }

    /**
     * 初始化默认部门数据。
     */
    @PostConstruct
    public void initDefaultDepts() {
        if (deptMap.isEmpty()) {
            Dept headOffice = new Dept(1L, "总部", 0L, 1, 1);
            headOffice.setCreateTime(LocalDateTime.now());
            headOffice.setUpdateTime(LocalDateTime.now());
            deptMap.put(1L, headOffice);

            Dept techDept = new Dept(2L, "技术部", 1L, 1, 1);
            techDept.setCreateTime(LocalDateTime.now());
            techDept.setUpdateTime(LocalDateTime.now());
            deptMap.put(2L, techDept);

            Dept salesDept = new Dept(3L, "销售部", 1L, 2, 1);
            salesDept.setCreateTime(LocalDateTime.now());
            salesDept.setUpdateTime(LocalDateTime.now());
            deptMap.put(3L, salesDept);

            Dept hrDept = new Dept(4L, "人事部", 1L, 3, 1);
            hrDept.setCreateTime(LocalDateTime.now());
            hrDept.setUpdateTime(LocalDateTime.now());
            deptMap.put(4L, hrDept);
        }
    }
}
