package com.example.demo.service;

import com.example.demo.model.BusinessItem;
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 BusinessService {

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

    private final AtomicLong idGenerator = new AtomicLong(500);

    /**
     * 新增业务数据。
     *
     * @requirement(name="业务新增", id="SRS-IMS_F-010")
     *
     * @param item 业务数据
     * @return 创建后的业务数据
     */
    public BusinessItem createBusinessItem(BusinessItem item) {
        long id = idGenerator.incrementAndGet();
        item.setId(id);
        item.setStatus("draft");
        item.setCreateTime(LocalDateTime.now());
        item.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, item);
        return item;
    }

    /**
     * 编辑业务数据（仅草稿状态可编辑）。
     *
     * @requirement(name="业务编辑", id="SRS-IMS_F-011")
     *
     * @param id   业务数据ID
     * @param item 更新后的业务数据
     * @return 更新后的业务数据
     */
    public BusinessItem updateBusinessItem(Long id, BusinessItem item) {
        BusinessItem existing = businessMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        if (!"draft".equals(existing.getStatus())) {
            throw new IllegalStateException("仅草稿状态的数据可编辑，当前状态: " + existing.getStatus());
        }
        if (item.getTitle() != null) {
            existing.setTitle(item.getTitle());
        }
        if (item.getContent() != null) {
            existing.setContent(item.getContent());
        }
        if (item.getType() != null) {
            existing.setType(item.getType());
        }
        existing.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, existing);
        return existing;
    }

    /**
     * 删除业务数据。
     *
     * @requirement(name="业务删除", id="SRS-IMS_F-012")
     *
     * @param id 业务数据ID
     */
    public void deleteBusinessItem(Long id) {
        if (!businessMap.containsKey(id)) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        businessMap.remove(id);
    }

    /**
     * 提交业务数据至审核流程（状态变更为 pending）。
     *
     * @requirement(name="业务提交", id="SRS-IMS_F-013")
     *
     * @param id 业务数据ID
     * @return 更新后的业务数据
     */
    public BusinessItem submitBusinessItem(Long id) {
        BusinessItem existing = businessMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        if (!"draft".equals(existing.getStatus())) {
            throw new IllegalStateException("仅草稿状态可提交，当前状态: " + existing.getStatus());
        }
        existing.setStatus("pending");
        existing.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, existing);
        return existing;
    }

    /**
     * 审核通过业务数据（状态变更为 approved）。
     *
     * @requirement(name="业务审核", id="SRS-IMS_F-014")
     *
     * @param id 业务数据ID
     * @return 更新后的业务数据
     */
    public BusinessItem approveBusinessItem(Long id) {
        BusinessItem existing = businessMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        if (!"pending".equals(existing.getStatus())) {
            throw new IllegalStateException("仅待审核状态可审核通过，当前状态: " + existing.getStatus());
        }
        existing.setStatus("approved");
        existing.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, existing);
        return existing;
    }

    /**
     * 驳回业务数据（状态变更为 rejected）。
     *
     * @requirement(name="业务驳回", id="SRS-IMS_F-015")
     *
     * @param id 业务数据ID
     * @return 更新后的业务数据
     */
    public BusinessItem rejectBusinessItem(Long id) {
        BusinessItem existing = businessMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        if (!"pending".equals(existing.getStatus())) {
            throw new IllegalStateException("仅待审核状态可驳回，当前状态: " + existing.getStatus());
        }
        existing.setStatus("rejected");
        existing.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, existing);
        return existing;
    }

    /**
     * 归档业务数据（状态变更为 archived）。
     *
     * @requirement(name="业务归档", id="SRS-IMS_F-016")
     *
     * @param id 业务数据ID
     * @return 更新后的业务数据
     */
    public BusinessItem archiveBusinessItem(Long id) {
        BusinessItem existing = businessMap.get(id);
        if (existing == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        if (!"approved".equals(existing.getStatus())) {
            throw new IllegalStateException("仅已通过状态可归档，当前状态: " + existing.getStatus());
        }
        existing.setStatus("archived");
        existing.setUpdateTime(LocalDateTime.now());
        businessMap.put(id, existing);
        return existing;
    }

    /**
     * 多条件组合查询业务数据。
     *
     * @requirement(name="查询筛选", id="SRS-IMS_F-017")
     * 支持按标题、类型、状态、创建人等多条件组合查询和分页。
     *
     * @param title   标题关键字（可选）
     * @param type    业务类型（可选）
     * @param status  状态（可选）
     * @param createdBy 创建人ID（可选）
     * @param page    页码（从0开始）
     * @param size    每页条数
     * @return 符合条件的业务数据列表
     */
    public List<BusinessItem> searchBusinessItems(String title, String type, String status,
                                                   Long createdBy, int page, int size) {
        List<BusinessItem> allItems = new ArrayList<>(businessMap.values());

        if (title != null && !title.isBlank()) {
            String kw = title.toLowerCase();
            allItems = allItems.stream()
                    .filter(item -> item.getTitle() != null && item.getTitle().toLowerCase().contains(kw))
                    .collect(Collectors.toList());
        }
        if (type != null && !type.isBlank()) {
            allItems = allItems.stream()
                    .filter(item -> type.equals(item.getType()))
                    .collect(Collectors.toList());
        }
        if (status != null && !status.isBlank()) {
            allItems = allItems.stream()
                    .filter(item -> status.equals(item.getStatus()))
                    .collect(Collectors.toList());
        }
        if (createdBy != null) {
            allItems = allItems.stream()
                    .filter(item -> createdBy.equals(item.getCreatedBy()))
                    .collect(Collectors.toList());
        }

        // 按创建时间倒序
        allItems.sort((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()));

        int start = page * size;
        if (start >= allItems.size()) {
            return List.of();
        }
        int end = Math.min(start + size, allItems.size());
        return allItems.subList(start, end);
    }

    /**
     * 根据ID获取业务数据。
     *
     * @param id 业务数据ID
     * @return 业务数据
     */
    public BusinessItem getBusinessItem(Long id) {
        BusinessItem item = businessMap.get(id);
        if (item == null) {
            throw new IllegalArgumentException("业务数据不存在，ID: " + id);
        }
        return item;
    }

    /**
     * 初始化默认业务数据。
     */
    @PostConstruct
    public void initDefaultItems() {
        if (businessMap.isEmpty()) {
            BusinessItem item1 = new BusinessItem(1L, "年度预算报告", "2024年度部门预算汇总报告", "财务", 1L, "approved");
            item1.setCreateTime(LocalDateTime.now().minusDays(5));
            item1.setUpdateTime(LocalDateTime.now().minusDays(1));
            businessMap.put(1L, item1);

            BusinessItem item2 = new BusinessItem(2L, "项目立项申请", "新系统开发项目立项申请", "项目", 2L, "pending");
            item2.setCreateTime(LocalDateTime.now().minusDays(2));
            item2.setUpdateTime(LocalDateTime.now().minusDays(2));
            businessMap.put(2L, item2);

            BusinessItem item3 = new BusinessItem(3L, "设备采购申请", "服务器及网络设备采购方案", "采购", 2L, "draft");
            item3.setCreateTime(LocalDateTime.now().minusDays(1));
            item3.setUpdateTime(LocalDateTime.now().minusDays(1));
            businessMap.put(3L, item3);
        }
    }
}
