package com.zioinfo.kintex.visitor.feed;

import com.zioinfo.kintex.common.error.ApiException;
import com.zioinfo.kintex.common.error.ErrorCode;
import com.zioinfo.kintex.visitor.feed.FeedDtos.FeedItemDto;
import com.zioinfo.kintex.visitor.feed.FeedDtos.RecordViewRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

/**
 * F-C7 최근 본 행사·부스 피드 서비스 — 조회 이력 저장 + 개인화 홈 피드.
 */
@Service
public class FeedService {

    private static final int DEFAULT_LIMIT = 20;

    private final FeedMapper mapper;

    public FeedService(FeedMapper mapper) {
        this.mapper = mapper;
    }

    /** 상세 진입 조회 이력 기록(멱등 upsert). */
    @Transactional
    public void record(String userId, RecordViewRequest req) {
        String type = normalizeType(req.itemType());
        Map<String, Object> row = new java.util.HashMap<>();
        row.put("id", "vvh-" + UUID.randomUUID());
        row.put("userId", userId);
        row.put("itemType", type);
        row.put("itemId", req.itemId().trim());
        row.put("itemTitle", req.itemTitle().trim());
        row.put("itemSub", req.itemSub());
        mapper.upsertView(row);
        mapper.prune(userId);
    }

    /** 최근 본 피드. */
    @Transactional(readOnly = true)
    public List<FeedItemDto> recent(String userId, int limit) {
        int lim = limit <= 0 || limit > 100 ? DEFAULT_LIMIT : limit;
        return mapper.listRecent(userId, lim).stream()
                .map(m -> new FeedItemDto(str(m.get("id")), str(m.get("itemType")), str(m.get("itemId")),
                        str(m.get("itemTitle")), str(m.get("itemSub")), str(m.get("viewedAt"))))
                .toList();
    }

    private static String normalizeType(String t) {
        String u = t == null ? "" : t.trim().toUpperCase(Locale.ROOT);
        if (!"EVENT".equals(u) && !"BOOTH".equals(u)) {
            throw new ApiException(ErrorCode.VALIDATION, "지원하지 않는 항목 유형입니다.");
        }
        return u;
    }

    private static String str(Object o) {
        return o == null ? null : o.toString();
    }
}
