package com.writeoff.module.meeting.repository;

import com.writeoff.module.meeting.model.Meeting;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@Repository
@ConditionalOnProperty(prefix = "app.repository", name = "mode", havingValue = "in-memory")
public class InMemoryMeetingRepository implements MeetingRepository {
    private final ConcurrentHashMap<Long, Meeting> store = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(2000);

    @Override
    public Meeting save(Meeting meeting) {
        if (meeting.getId() == null) {
            Meeting newMeeting = new Meeting(
                    idGenerator.incrementAndGet(),
                    meeting.getProjectId(),
                    meeting.getTopic(),
                    meeting.getMeetingCategory(),
                    meeting.getMeetingForm(),
                    meeting.getLocation(),
                    meeting.getStartTime(),
                    meeting.getEndTime(),
                    meeting.getBudgetCent(),
                    meeting.getLaborRatio(),
                    meeting.getCateringRatio(),
                    meeting.getStatus(),
                    meeting.getAuditStatus(),
                    meeting.getCurrentAuditNode(),
                    meeting.getLastSubmitAt(),
                    meeting.getLastRejectReason(),
                    meeting.getOverdueDays(),
                    meeting.getRiskFlagsJson(),
                    meeting.isFrozen(),
                    meeting.getFreezeReason(),
                    meeting.getCurrentAuditorUserId(),
                    meeting.getNodeDeadlineAt(),
                    meeting.getRejectCount(),
                    meeting.getLastActionAt(),
                    meeting.getStatusChangedAt(),
                    meeting.getStatusChangedBy(),
                    meeting.getCancelReason(),
                    meeting.getPostponeReason(),
                    meeting.getWithdrawReason(),
                    meeting.getLockVersion(),
                    meeting.getLockAt(),
                    meeting.getLockedBy(),
                    meeting.getInvoiceConfigJson()
            );
            store.put(newMeeting.getId(), newMeeting);
            return newMeeting;
        }
        store.put(meeting.getId(), meeting);
        return meeting;
    }

    @Override
    public Optional<Meeting> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }

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

    @Override
    public void softDelete(Long id) {
        Meeting meeting = store.get(id);
        if (meeting != null) {
            meeting.setDeleted(true);
            store.put(id, meeting);
        }
    }
}
