package com.example.demo.repository;

import com.example.demo.model.*;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;

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

/**
 * 内存数据存储组件。
 *
 * <p>使用 ConcurrentHashMap 模拟数据库存储，提供各实体的 CRUD 访问能力。
 * 项目初始化时预置若干假数据，确保应用可立即运行演示。</p>
 *
 * <p><b>后续扩展：</b>可替换为 JPA/MyBatis-Plus 等持久化框架实现真实数据库存储。</p>
 */
@Component
public class InMemoryDataStore {

    // ==================== 模拟自增 ID 生成器 ====================
    private final AtomicLong userIdSeq = new AtomicLong(100);
    private final AtomicLong roleIdSeq = new AtomicLong(10);
    private final AtomicLong deptIdSeq = new AtomicLong(10);
    private final AtomicLong businessIdSeq = new AtomicLong(1000);
    private final AtomicLong logIdSeq = new AtomicLong(5000);
    private final AtomicLong dictIdSeq = new AtomicLong(50);
    private final AtomicLong configIdSeq = new AtomicLong(20);

    // ==================== 数据存储容器 ====================
    private final Map<Long, User> users = new ConcurrentHashMap<>();
    private final Map<Long, Role> roles = new ConcurrentHashMap<>();
    private final Map<Long, Dept> depts = new ConcurrentHashMap<>();
    private final Map<Long, BusinessItem> businessItems = new ConcurrentHashMap<>();
    private final Map<Long, LogRecord> logs = new ConcurrentHashMap<>();
    private final Map<Long, DictItem> dictItems = new ConcurrentHashMap<>();
    private final Map<Long, SystemConfig> systemConfigs = new ConcurrentHashMap<>();

    // ==================== 预置权限树 ====================
    private final List<TreeNode> permissionTree = new ArrayList<>();

    // ==================== User 操作 ====================

    public long nextUserId() { return userIdSeq.incrementAndGet(); }

    public Map<Long, User> getUserMap() { return users; }

    public User saveUser(User user) {
        users.put(user.getUserId(), user);
        return user;
    }

    public Optional<User> findUserById(Long id) { return Optional.ofNullable(users.get(id)); }

    public List<User> findAllUsers() { return new ArrayList<>(users.values()); }

    public void deleteUserById(Long id) { users.remove(id); }

    // ==================== Role 操作 ====================

    public long nextRoleId() { return roleIdSeq.incrementAndGet(); }

    public Map<Long, Role> getRoleMap() { return roles; }

    public Role saveRole(Role role) {
        roles.put(role.getRoleId(), role);
        return role;
    }

    public Optional<Role> findRoleById(Long id) { return Optional.ofNullable(roles.get(id)); }

    public List<Role> findAllRoles() { return new ArrayList<>(roles.values()); }

    public void deleteRoleById(Long id) { roles.remove(id); }

    // ==================== Dept 操作 ====================

    public long nextDeptId() { return deptIdSeq.incrementAndGet(); }

    public Map<Long, Dept> getDeptMap() { return depts; }

    public Dept saveDept(Dept dept) {
        depts.put(dept.getDeptId(), dept);
        return dept;
    }

    public Optional<Dept> findDeptById(Long id) { return Optional.ofNullable(depts.get(id)); }

    public List<Dept> findAllDepts() { return new ArrayList<>(depts.values()); }

    public void deleteDeptById(Long id) { depts.remove(id); }

    // ==================== BusinessItem 操作 ====================

    public long nextBusinessId() { return businessIdSeq.incrementAndGet(); }

    public Map<Long, BusinessItem> getBusinessMap() { return businessItems; }

    public BusinessItem saveBusiness(BusinessItem item) {
        businessItems.put(item.getId(), item);
        return item;
    }

    public Optional<BusinessItem> findBusinessById(Long id) { return Optional.ofNullable(businessItems.get(id)); }

    public List<BusinessItem> findAllBusiness() { return new ArrayList<>(businessItems.values()); }

    public void deleteBusinessById(Long id) { businessItems.remove(id); }

    // ==================== Log 操作 ====================

    public long nextLogId() { return logIdSeq.incrementAndGet(); }

    public LogRecord saveLog(LogRecord log) {
        logs.put(log.getLogId(), log);
        return log;
    }

    public List<LogRecord> findAllLogs() { return new ArrayList<>(logs.values()); }

    // ==================== Dict 操作 ====================

    public long nextDictId() { return dictIdSeq.incrementAndGet(); }

    public Map<Long, DictItem> getDictMap() { return dictItems; }

    public DictItem saveDict(DictItem item) {
        dictItems.put(item.getDictId(), item);
        return item;
    }

    public Optional<DictItem> findDictById(Long id) { return Optional.ofNullable(dictItems.get(id)); }

    public List<DictItem> findAllDicts() { return new ArrayList<>(dictItems.values()); }

    public void deleteDictById(Long id) { dictItems.remove(id); }

    // ==================== Config 操作 ====================

    public long nextConfigId() { return configIdSeq.incrementAndGet(); }

    public Map<Long, SystemConfig> getConfigMap() { return systemConfigs; }

    public SystemConfig saveConfig(SystemConfig config) {
        systemConfigs.put(config.getConfigId(), config);
        return config;
    }

    public Optional<SystemConfig> findConfigById(Long id) { return Optional.ofNullable(systemConfigs.get(id)); }

    public List<SystemConfig> findAllConfigs() { return new ArrayList<>(systemConfigs.values()); }

    public void deleteConfigById(Long id) { systemConfigs.remove(id); }

    // ==================== 权限树 ====================

    public List<TreeNode> getPermissionTree() { return permissionTree; }

    // ==================== 初始化假数据 ====================

    /**
     * 项目启动时初始化预置假数据，确保应用可直接运行演示。
     */
    @PostConstruct
    public void initMockData() {
        initRoles();
        initDepts();
        initUsers();
        initBusinessItems();
       initDictItems();
        initConfigs();
        initPermissionTree();
        initLogs();
    }

    private void initRoles() {
        Role admin = new Role(1L, "超级管理员", "SUPER_ADMIN", "系统超级管理员", 1, true,
                List.of("*"));
        Role user = new Role(2L, "普通用户", "NORMAL_USER", "普通业务用户", 1, false,
                List.of("business:view", "business:add", "business:edit", "business:submit"));
        roles.put(1L, admin);
        roles.put(2L, user);
    }

    private void initDepts() {
        Dept head = new Dept(1L, "总公司", 0L, 1, 1, new ArrayList<>());
        Dept dept1 = new Dept(2L, "技术部", 1L, 1, 1, new ArrayList<>());
        Dept dept2 = new Dept(3L, "市场部", 1L, 2, 1, new ArrayList<>());
        depts.put(1L, head);
        depts.put(2L, dept1);
        depts.put(3L, dept2);
    }

    private void initUsers() {
        User u1 = new User(1L, "admin", "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy",
                "系统管理员", 1L, 1L, "13800000000", 1);
        User u2 = new User(2L, "zhangsan", "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy",
                "张三", 2L, 2L, "13900000001", 1);
        User u3 = new User(3L, "lisi", "$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy",
                "李四", 3L, 2L, "13900000002", 1);
        users.put(1L, u1);
        users.put(2L, u2);
        users.put(3L, u3);
    }

    private void initBusinessItems() {
        long now = System.currentTimeMillis();
        BusinessItem b1 = new BusinessItem(1L, "采购申请单-001", "申请采购服务器设备", "采购", "admin", "APPROVED", "审核通过", now - 86400000L, now - 43200000L);
        BusinessItem b2 = new BusinessItem(2L, "报销申请单-001", "差旅费用报销", "报销", "zhangsan", "SUBMITTED", null, now - 72000000L, now - 36000000L);
        BusinessItem b3 = new BusinessItem(3L, "合同审批-001", "年度服务合同续签", "合同", "lisi", "DRAFT", null, now - 36000000L, now - 18000000L);
        BusinessItem b4 = new BusinessItem(4L, "采购申请单-002", "申请采购办公家具", "采购", "zhangsan", "REJECTED", "预算不足，请重新规划", now - 172800000L, now - 86400000L);
        BusinessItem b5 = new BusinessItem(5L, "归档项目-001", "已完成项目归档", "项目", "admin", "ARCHIVED", "归档完成", now - 259200000L, now - 172800000L);
        businessItems.put(1L, b1);
        businessItems.put(2L, b2);
        businessItems.put(3L, b3);
        businessItems.put(4L, b4);
        businessItems.put(5L, b5);
    }

    private void initDictItems() {
        dictItems.put(1L, new DictItem(1L, "business_type", "业务类型", "采购", "采购", 1, 1));
        dictItems.put(2L, new DictItem(2L, "business_type", "业务类型", "报销", "报销", 2, 1));
        dictItems.put(3L, new DictItem(3L, "business_type", "业务类型", "合同", "合同", 3, 1));
        dictItems.put(4L, new DictItem(4L, "business_status", "业务状态", "DRAFT", "草稿", 1, 1));
        dictItems.put(5L, new DictItem(5L, "business_status", "业务状态", "SUBMITTED", "已提交", 2, 1));
        dictItems.put(6L, new DictItem(6L, "business_status", "业务状态", "APPROVED", "已通过", 3, 1));
        dictItems.put(7L, new DictItem(7L, "business_status", "业务状态", "REJECTED", "已驳回", 4, 1));
        dictItems.put(8L, new DictItem(8L, "business_status", "业务状态", "ARCHIVED", "已归档", 5, 1));
    }

    private void initConfigs() {
        systemConfigs.put(1L, new SystemConfig(1L, "system.title", "信息管理系统", "系统标题", 1));
        systemConfigs.put(2L, new SystemConfig(2L, "system.version", "1.0.0", "系统版本", 1));
        systemConfigs.put(3L, new SystemConfig(3L, "business.auto_archive_days", "30", "业务数据自动归档天数", 1));
    }

    private void initPermissionTree() {
        TreeNode userMgmt = new TreeNode("01", "用户管理", "MENU", "", "", "/user", "user", 1, new ArrayList<>());
        userMgmt.setChildren(List.of(
                new TreeNode("0101", "查询用户", "BUTTON", "user:view", "01", "", "", 1, new ArrayList<>()),
                new TreeNode("0102", "新增用户", "BUTTON", "user:add", "01", "", "", 2, new ArrayList<>()),
                new TreeNode("0103", "编辑用户", "BUTTON", "user:edit", "01", "", "", 3, new ArrayList<>()),
                new TreeNode("0104", "删除用户", "BUTTON", "user:delete", "01", "", "", 4, new ArrayList<>())
        ));

        TreeNode roleMgmt = new TreeNode("02", "角色管理", "MENU", "", "", "/role", "role", 2, new ArrayList<>());
        roleMgmt.setChildren(List.of(
                new TreeNode("0201", "查询角色", "BUTTON", "role:view", "02", "", "", 1, new ArrayList<>()),
                new TreeNode("0202", "新增角色", "BUTTON", "role:add", "02", "", "", 2, new ArrayList<>()),
                new TreeNode("0203", "编辑角色", "BUTTON", "role:edit", "02", "", "", 3, new ArrayList<>()),
                new TreeNode("0204", "删除角色", "BUTTON", "role:delete", "02", "", "", 4, new ArrayList<>()),
                new TreeNode("0205", "权限分配", "BUTTON", "role:permission", "02", "", "", 5, new ArrayList<>())
        ));

        TreeNode deptMgmt = new TreeNode("03", "部门管理", "MENU", "", "", "/dept", "dept", 3, new ArrayList<>());
        deptMgmt.setChildren(List.of(
                new TreeNode("0301", "查询部门", "BUTTON", "dept:view", "03", "", "", 1, new ArrayList<>()),
                new TreeNode("0302", "新增部门", "BUTTON", "dept:add", "03", "", "", 2, new ArrayList<>()),
                new TreeNode("0303", "编辑部门", "BUTTON", "dept:edit", "03", "", "", 3, new ArrayList<>()),
                new TreeNode("0304", "删除部门", "BUTTON", "dept:delete", "03", "", "", 4, new ArrayList<>())
        ));

        TreeNode business = new TreeNode("04", "业务管理", "MENU", "", "", "/business", "business", 4, new ArrayList<>());
        business.setChildren(List.of(
                new TreeNode("0401", "查看业务", "BUTTON", "business:view", "04", "", "", 1, new ArrayList<>()),
                new TreeNode("0402", "新增业务", "BUTTON", "business:add", "04", "", "", 2, new ArrayList<>()),
                new TreeNode("0403", "编辑业务", "BUTTON", "business:edit", "04", "", "", 3, new ArrayList<>()),
                new TreeNode("0404", "删除业务", "BUTTON", "business:delete", "04", "", "", 4, new ArrayList<>()),
                new TreeNode("0405", "提交审核", "BUTTON", "business:submit", "04", "", "", 5, new ArrayList<>()),
                new TreeNode("0406", "审核业务", "BUTTON", "business:approve", "04", "", "", 6, new ArrayList<>()),
                new TreeNode("0407", "驳回业务", "BUTTON", "business:reject", "04", "", "", 7, new ArrayList<>()),
                new TreeNode("0408", "归档业务", "BUTTON", "business:archive", "04", "", "", 8, new ArrayList<>())
        ));

        TreeNode stats = new TreeNode("05", "统计分析", "MENU", "", "", "/stats", "chart", 5, new ArrayList<>());
        stats.setChildren(List.of(
                new TreeNode("0501", "数据汇总", "BUTTON", "stats:summary", "05", "", "", 1, new ArrayList<>()),
                new TreeNode("0502", "图表查看", "BUTTON", "stats:chart", "05", "", "", 2, new ArrayList<>()),
                new TreeNode("0503", "自定义查询", "BUTTON", "stats:custom-query", "05", "", "", 3, new ArrayList<>()),
                new TreeNode("0504", "报表导出", "BUTTON", "stats:export", "05", "", "", 4, new ArrayList<>()),
                new TreeNode("0505", "台账生成", "BUTTON", "stats:ledger", "05", "", "", 5, new ArrayList<>())
        ));

        TreeNode logMgmt = new TreeNode("06", "日志审计", "MENU", "", "", "/log", "log", 6, new ArrayList<>());
        logMgmt.setChildren(List.of(
                new TreeNode("0601", "查询日志", "BUTTON", "log:view", "06", "", "", 1, new ArrayList<>())
        ));

        TreeNode sysMgmt = new TreeNode("07", "系统配置", "MENU", "", "", "/system", "system", 7, new ArrayList<>());
        sysMgmt.setChildren(List.of(
                new TreeNode("0701", "字典管理", "BUTTON", "dict:view", "07", "", "", 1, new ArrayList<>()),
                new TreeNode("0702", "参数配置", "BUTTON", "config:view", "07", "", "", 2, new ArrayList<>())
        ));

        permissionTree.clear();
        permissionTree.addAll(List.of(userMgmt, roleMgmt, deptMgmt, business, stats, logMgmt, sysMgmt));
    }

    private void initLogs() {
        long now = System.currentTimeMillis();
        logs.put(1L, new LogRecord(1L, "LOGIN", "admin", "用户登录系统", "192.168.1.100", "SUCCESS", null, now - 86400000L));
        logs.put(2L, new LogRecord(2L, "LOGIN", "zhangsan", "用户登录系统", "192.168.1.101", "SUCCESS", null, now - 72000000L));
        logs.put(3L, new LogRecord(3L, "OPERATION", "admin", "新增用户：wangwu", "192.168.1.100", "SUCCESS", null, now - 43200000L));
        logs.put(4L, new LogRecord(4L, "OPERATION", "zhangsan", "提交业务数据：采购申请单-002", "192.168.1.101", "SUCCESS", null, now - 36000000L));
        logs.put(5L, new LogRecord(5L, "EXCEPTION", "lisi", "系统异常：NullPointerException", "192.168.1.102", "FAIL", "java.lang.NullPointerException: Cannot invoke ...", now - 18000000L));
        logs.put(6L, new LogRecord(6L, "OPERATION", "admin", "审核通过：采购申请单-001", "192.168.1.100", "SUCCESS", null, now - 3600000L));
    }
}
