package com.example.demo.repository.impl;

import com.example.demo.model.TaskDraft;
import com.example.demo.repository.TaskDraftRepository;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 任务草案仓储内存实现。
 * <p>
 * 使用 ConcurrentHashMap 模拟数据库存储。
 * 后续可替换为 MyBatis/JPA 等数据库实现。
 * </p>
 *
 * @requirement(name="任务草案发送与重试机制", id="SRS-EHTG-07")
 * 向下游任务规划引擎发送请求，失败时自动加入本地重试队列。
 */
@Repository
public class InMemoryTaskDraftRepository implements TaskDraftRepository {

    private final ConcurrentHashMap<String, TaskDraft> store = new ConcurrentHashMap<>();
    private final AtomicLong idCounter = new AtomicLong(0);

    @Override
    public TaskDraft save(TaskDraft draft) {
        if (draft.getDraftId() == null || draft.getDraftId().isEmpty()) {
            String id = "DRF-" + String.format("%03d", idCounter.incrementAndGet());
            draft.setDraftId(id);
        }
        if (draft.getCreateTime() == null) {
            draft.setCreateTime(LocalDateTime.now());
        }
        store.put(draft.getDraftId(), draft);
        return draft;
    }

    @Override
    public Optional<TaskDraft> findById(String draftId) {
        return Optional.ofNullable(store.get(draftId));
    }

    @Override
    public List<TaskDraft> findByEventId(String eventId) {
        return store.values().stream()
                .filter(d -> eventId.equals(d.getEventId()))
                .collect(Collectors.toList());
    }

    @Override
    public List<TaskDraft> findAll() {
        return new ArrayList<>(store.values());
    }

    @Override
    public List<TaskDraft> findAllFailed() {
        return store.values().stream()
                .filter(d -> d.getSendStatus() == 2)
                .collect(Collectors.toList());
    }

    @Override
    public Optional<TaskDraft> updateSendStatus(String draftId, int sendStatus, int retryCount) {
        return Optional.ofNullable(store.computeIfPresent(draftId, (id, draft) -> {
            draft.setSendStatus(sendStatus);
            draft.setRetryCount(retryCount);
            draft.setLastSendTime(LocalDateTime.now());
            return draft;
        }));
    }
}
