package com.example.demo.service;

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

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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> businessMap = new ConcurrentHashMap<>();
    private final AtomicLong idCounter = new AtomicLong(1);
    private final AtomicLong noCounter = new AtomicLong(20260001);

    public BusinessService() {
        long b1 = idCounter.getAndIncrement();
        businessMap.put(b1, new BusinessItem(b1, "BIZ20260001", "leave", 2L, "张三",
                "2026-01-10 09:00:00", "请年假5天", "draft"));
        long b2 = idCounter.getAndIncrement();
        businessMap.put(b2, new BusinessItem(b2, "BIZ20260002", "expense", 2L, "张三",
                "2026-01-11 10:30:00", "报销差旅费3000元", "submitted"));
        BusinessItem b2item = businessMap.get(b2);
        b2item.setReviewerId(1L);
        b2item.setReviewerName("系统管理员");
        long b3 = idCounter.getAndIncrement();
        businessMap.put(b3, new BusinessItem(b3, "BIZ20260003", "purchase", 2L, "张三",
                "2026-01-12 14:00:00", "采购办公用品", "approved"));
        BusinessItem b3item = businessMap.get(b3);
        b3item.setReviewerId(1L);
        b3item.setReviewerName("系统管理员");
        b3item.setReviewComment("同意采购");
    }

    private String now() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 新增业务。
     *
     * @requirement(name="业务新增", id="SRS-F-02-001")
     * 用户创建新的业务记录。
     */
    public BusinessItem addBusiness(BusinessItem item) {
        long id = idCounter.getAndIncrement();
        item.setId(id);
        item.setBusinessNo("BIZ" + noCounter.getAndIncrement());
        item.setApplyTime(now());
        if (item.getStatus() == null) {
            item.setStatus("draft");
        }
        businessMap.put(id, item);
        return item;
    }

    /**
     * 编辑业务。
     *
     * @requirement(name="业务编辑", id="SRS-F-02-002")
     * 修改已有业务记录（仅草稿状态可编辑）。
     */
    public BusinessItem editBusiness(BusinessItem item) {
        BusinessItem existing = businessMap.get(item.getId());
        if (existing == null) throw new RuntimeException("业务不存在");
        if (!"draft".equals(existing.getStatus())) {
            throw new RuntimeException("仅草稿状态的业务可编辑");
        }
        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")
     * 根据ID删除业务记录（仅草稿状态可删除）。
     */
    public void deleteBusiness(Long id) {
        BusinessItem item = businessMap.get(id);
        if (item == null) throw new RuntimeException("业务不存在");
        if (!"draft".equals(item.getStatus())) {
            throw new RuntimeException("仅草稿状态的业务可删除");
        }
        businessMap.remove(id);
    }

    /**
     * 提交业务。
     *
     * @requirement(name="业务提交", id="SRS-F-02-004")
     * 用户将业务提交给指定审核人，状态变为已提交。
     */
    public BusinessItem submitBusiness(Long id, Long reviewerId, String reviewerName) {
        BusinessItem item = businessMap.get(id);
        if (item == null) throw new RuntimeException("业务不存在");
        if (!"draft".equals(item.getStatus())) {
            throw new RuntimeException("仅草稿状态的业务可提交");
        }
        item.setStatus("submitted");
        item.setReviewerId(reviewerId);
        item.setReviewerName(reviewerName);
        return item;
    }

    /**
     * 审核通过业务。
     *
     * @requirement(name="业务审核", id="SRS-F-02-005")
     * 审核人通过业务申请，状态变为已通过。
     */
    public BusinessItem approveBusiness(Long id, String comment) {
        BusinessItem item = businessMap.get(id);
        if (item == null) throw new RuntimeException("业务不存在");
        if (!"submitted".equals(item.getStatus())) {
            throw new RuntimeException("仅已提交状态的业务可审核");
        }
        item.setStatus("approved");
        item.setReviewComment(comment);
        return item;
    }

    /**
     * 驳回业务。
     *
     * @requirement(name="业务驳回", id="SRS-F-02-006")
     * 审核人驳回业务申请，状态变为已驳回。
     */
    public BusinessItem rejectBusiness(Long id, String comment) {
        BusinessItem item = businessMap.get(id);
        if (item == null) throw new RuntimeException("业务不存在");
        if (!"submitted".equals(item.getStatus())) {
            throw new RuntimeException("仅已提交状态的业务可驳回");
        }
        item.setStatus("rejected");
        item.setReviewComment(comment);
        return item;
    }

    /**
     * 归档业务。
     *
     * @requirement(name="业务归档", id="SRS-F-02-007")
     * 将已通过的业务进行归档锁定。
     */
    public BusinessItem archiveBusiness(Long id) {
        BusinessItem item = businessMap.get(id);
        if (item == null) throw new RuntimeException("业务不存在");
        if (!"approved".equals(item.getStatus())) {
            throw new RuntimeException("仅已通过状态的业务可归档");
        }
        item.setStatus("archived");
        return item;
    }

    /**
     * 查询业务列表（支持按类型、状态、日期范围筛选）。
     *
     * @requirement(name="业务查询筛选", id="SRS-F-02-008")
     * 支持按业务类型、状态、日期范围等多条件筛选查询。
     */
    public List<BusinessItem> listBusinesses(String businessType, String status,
                                              String dateFrom, String dateTo, int page, int size) {
        List<BusinessItem> all = new ArrayList<>(businessMap.values());
        if (businessType != null && !businessType.isEmpty()) {
            all = all.stream().filter(b -> businessType.equals(b.getBusinessType())).collect(Collectors.toList());
        }
        if (status != null && !status.isEmpty()) {
            all = all.stream().filter(b -> status.equals(b.getStatus())).collect(Collectors.toList());
        }
        if (dateFrom != null && !dateFrom.isEmpty()) {
            all = all.stream().filter(b -> b.getApplyTime() != null && b.getApplyTime().compareTo(dateFrom) >= 0)
                    .collect(Collectors.toList());
        }
        if (dateTo != null && !dateTo.isEmpty()) {
            all = all.stream().filter(b -> b.getApplyTime() != null && b.getApplyTime().compareTo(dateTo) <= 0)
                    .collect(Collectors.toList());
        }
        int start = (page - 1) * size;
        int end = Math.min(start + size, all.size());
        if (start >= all.size()) return new ArrayList<>();
        return all.subList(start, end);
    }

    /**
     * 根据ID查询业务。
     */
    public BusinessItem getBusinessById(Long id) {
        return businessMap.get(id);
    }
}
