package kr.itn.itnhub.timeline;

import kr.itn.itnhub.feed.FileView;
import kr.itn.itnhub.mattermost.MattermostClient;
import kr.itn.itnhub.memo.WorkMemo;
import kr.itn.itnhub.memo.WorkMemoMapper;
import kr.itn.itnhub.org.OrgNotFoundException;
import kr.itn.itnhub.org.Organization;
import kr.itn.itnhub.org.OrganizationMapper;
import kr.itn.itnhub.stage.StageHistoryMapper;
import kr.itn.itnhub.stage.StageHistoryRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 기관관리 상세의 타임라인 탭이 쓰는 서비스. 단계변경 이력(stage_history) + 업무메모(work_memo) +
 * 채널 첨부파일(Mattermost)을 한 번에 모아 최신순으로 합쳐 돌려준다.
 *
 * <p>Mattermost 조회는 채널별로 개별 catch한다 - 한쪽 채널(혹은 Mattermost 서버 자체)이
 * 실패해도 이미 DB에서 구한 단계·메모 이력까지 통째로 못 보여줄 이유가 없다.</p>
 */
@Service
public class TimelineService {

    private static final Logger log = LoggerFactory.getLogger(TimelineService.class);

    private static final String LABEL_MJ = "문정원";
    private static final String LABEL_LAW = "법률검토";

    /** 메모 상세문(detail)로 보여줄 첫 줄의 최대 길이. */
    private static final int MEMO_DETAIL_MAX_LEN = 60;

    private final OrganizationMapper orgMapper;
    private final StageHistoryMapper stageHistoryMapper;
    private final WorkMemoMapper memoMapper;
    private final MattermostClient mattermost;

    public TimelineService(OrganizationMapper orgMapper, StageHistoryMapper stageHistoryMapper,
                           WorkMemoMapper memoMapper, MattermostClient mattermost) {
        this.orgMapper = orgMapper;
        this.stageHistoryMapper = stageHistoryMapper;
        this.memoMapper = memoMapper;
        this.mattermost = mattermost;
    }

    public List<TimelineEvent> timeline(Long orgId) {
        Organization org = orgMapper.findById(orgId);
        if (org == null) {
            throw new OrgNotFoundException("기관을 찾을 수 없습니다: " + orgId);
        }

        List<TimelineEvent> events = new ArrayList<>();

        for (StageHistoryRow row : stageHistoryMapper.findByOrg(orgId)) {
            events.add(new TimelineEvent("STAGE", row.getChangedAt(), String.valueOf(row.getStage()), null));
        }

        for (WorkMemo memo : memoMapper.findByOrg(orgId)) {
            events.add(new TimelineEvent("MEMO", memo.getCreatedAt(), memo.getContactName(),
                    firstLine(memo.getBody())));
        }

        events.addAll(fileEvents(org.getChannelIdMj(), LABEL_MJ));
        events.addAll(fileEvents(org.getChannelIdLaw(), LABEL_LAW));

        events.sort(Comparator.comparingLong(TimelineEvent::at).reversed());
        return events;
    }

    private List<TimelineEvent> fileEvents(String channelId, String channelLabel) {
        if (channelId == null || channelId.isBlank()) {
            return List.of();
        }
        try {
            List<FileView> files = mattermost.collectChannelFiles(channelId);
            List<TimelineEvent> events = new ArrayList<>(files.size());
            for (FileView file : files) {
                events.add(new TimelineEvent("FILE", file.createAt(), file.name(),
                        channelLabel + " · " + file.uploader()));
            }
            return events;
        } catch (RuntimeException e) {
            log.warn("타임라인 자료 조회 실패 channel={}", channelLabel, e);
            return List.of();
        }
    }

    private String firstLine(String body) {
        if (body == null) {
            return "";
        }
        String line = body.strip().split("\\R", 2)[0];
        if (line.length() > MEMO_DETAIL_MAX_LEN) {
            return line.substring(0, MEMO_DETAIL_MAX_LEN);
        }
        return line;
    }
}
