package com.example.demo.service;

import com.example.demo.model.BusinessItem;
import org.springframework.stereotype.Service;

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

/**
 * 业务管理服务。
 * <p>基于内存数据存储，提供业务的新增、编辑、删除、提交、审核、驳回、归档及查询筛选。</p>
 */
@Service
public class BusinessService {

    private final Map<Long, BusinessItem> businessStore = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1);
    private final AtomicLong bizNoCounter = new AtomicLong(1);

    public BusinessService() {
        initMockData();
    }

    private void initMockData() {
        save(new BusinessItem(1L, "BIZ-2024-001", "采购申请", 1L,
                "2024-01-15 10:00:00", "申请采购服务器设备", "/attachments/biz_001.pdf",
                "已归档", 2L, "同意"));
        save(new BusinessItem(2L, "BIZ-2024-002", "请假申请", 2L,
                "2024-01-16 14:00:00", "年假申请", null,
                "待审核", null, null));
        save(new BusinessItem(3L, "BIZ-2024-003", "报销申请", 1L,
                "2024-01-17 09:00:00", "差旅报销", "/attachments/biz_003.pdf",
                "草稿", null, null));
        idGenerator.set(4);
        bizNoCounter.set(4);
    }

    /**
     * 新增业务。
     *
     * @requirement(name="业务新增", id="SRS-F-02-001")
     * @param item 业务信息
     * @return 已保存的业务
     */
    public BusinessItem save(BusinessItem item) {
        if (item.getBusinessId() == null) {
            item.setBusinessId(idGenerator.getAndIncrement());
        }
        if (item.getBusinessNo() == null) {
            item.setBusinessNo("BIZ-" + java.time.Year.now() + "-" +
                    String.format("%03d", bizNoCounter.getAndIncrement()));
        }
        if (item.getApplyTime() == null) {
            item.setApplyTime(java.time.LocalDateTime.now().toString().replace("T", " "));
        }
        if (item.getStatus() == null) {
            item.setStatus("草稿");
        }
        businessStore.put(item.getBusinessId(), item);
        return item;
    }

    /**
     * 编辑业务信息。
     *
     * @requirement(name="业务编辑", id="SRS-F-02-002")
     * @param item 包含更新信息的业务对象
     * @return 更新后的业务，若ID不存在返回 null
     */
    public BusinessItem update(BusinessItem item) {
        BusinessItem existing = businessStore.get(item.getBusinessId());
        if (existing == null) return null;
        if (!"草稿".equals(existing.getStatus())) return null; // 仅草稿可编辑
        if (item.getBusinessType() != null) existing.setBusinessType(item.getBusinessType());
        if (item.getContent() != null) existing.setContent(item.getContent());
        if (item.getAttachmentPath() != null) existing.setAttachmentPath(item.getAttachmentPath());
        return existing;
    }

    /**
     * 删除业务。
     *
     * @requirement(name="业务删除", id="SRS-F-02-003")
     * @param businessId 业务ID
     * @return 是否删除成功
     */
    public boolean deleteById(Long businessId) {
        BusinessItem existing = businessStore.get(businessId);
        if (existing == null) return false;
        if (!"草稿".equals(existing.getStatus())) return false; // 仅草稿可删除
        return businessStore.remove(businessId) != null;
    }

    /**
     * 提交业务（草稿 → 待审核）。
     *
     * @requirement(name="业务提交", id="SRS-F-02-004")
     * @param businessId 业务ID
     * @return 操作后的业务，若状态不合法返回 null
     */
    public BusinessItem submit(Long businessId) {
        BusinessItem item = businessStore.get(businessId);
        if (item == null) return null;
        if (!"草稿".equals(item.getStatus())) return null;
        item.setStatus("待审核");
        return item;
    }

    /**
     * 审核通过业务（待审核 → 通过）。
     *
     * @requirement(name="业务审核", id="SRS-F-02-005")
     * @param businessId 业务ID
     * @param auditorId  审核人ID
     * @param comment    审核意见
     * @return 操作后的业务，若状态不合法返回 null
     */
    public BusinessItem approve(Long businessId, Long auditorId, String comment) {
        BusinessItem item = businessStore.get(businessId);
        if (item == null) return null;
        if (!"待审核".equals(item.getStatus())) return null;
        item.setStatus("通过");
        item.setAuditorId(auditorId);
        item.setComment(comment != null ? comment : "同意");
        return item;
    }

    /**
     * 驳回业务（待审核 → 驳回）。
     *
     * @requirement(name="业务驳回", id="SRS-F-02-006")
     * @param businessId 业务ID
     * @param auditorId  审核人ID
     * @param comment    驳回原因
     * @return 操作后的业务，若状态不合法返回 null
     */
    public BusinessItem reject(Long businessId, Long auditorId, String comment) {
        BusinessItem item = businessStore.get(businessId);
        if (item == null) return null;
        if (!"待审核".equals(item.getStatus())) return null;
        item.setStatus("驳回");
        item.setAuditorId(auditorId);
        item.setComment(comment != null ? comment : "驳回");
        return item;
    }

    /**
     * 归档业务（通过 → 已归档）。
     *
     * @requirement(name="业务归档", id="SRS-F-02-007")
     * @param businessId 业务ID
     * @return 操作后的业务，若状态不合法返回 null
     */
    public BusinessItem archive(Long businessId) {
        BusinessItem item = businessStore.get(businessId);
        if (item == null) return null;
        if (!"通过".equals(item.getStatus())) return null;
        item.setStatus("已归档");
        return item;
    }

    /**
     * 查询业务列表，支持按类型、状态、关键字筛选。
     *
     * @requirement(name="业务查询筛选", id="SRS-F-02-008")
     * @param businessType 业务类型（可选）
     * @param status       状态（可选）
     * @param keyword      关键字（可选，匹配业务编号和内容）
     * @return 业务列表
     */
    public List<BusinessItem> list(String businessType, String status, String keyword) {
        return businessStore.values().stream()
                .filter(b -> businessType == null || b.getBusinessType().equals(businessType))
                .filter(b -> status == null || b.getStatus().equals(status))
                .filter(b -> keyword == null || b.getBusinessNo().contains(keyword)
                        || b.getContent().contains(keyword))
                .sorted(Comparator.comparingLong(BusinessItem::getBusinessId).reversed())
                .collect(Collectors.toList());
    }

    /**
     * 根据ID查询业务。
     *
     * @param businessId 业务ID
     * @return 业务对象
     */
    public BusinessItem findById(Long businessId) {
        return businessStore.get(businessId);
    }

    /**
     * 获取所有业务列表。
     *
     * @return 所有业务
     */
    public List<BusinessItem> findAll() {
        return new ArrayList<>(businessStore.values());
    }
}
