package kr.itn.itnhub.review;

import kr.itn.itnhub.org.OrgNotFoundException;
import kr.itn.itnhub.org.OrganizationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class ReviewImportService {

    private final ReviewParser parser;
    private final ReviewItemMapper mapper;
    private final OrganizationMapper orgMapper;
    private final TransactionTemplate transactionTemplate;

    public ReviewImportService(ReviewParser parser, ReviewItemMapper mapper, OrganizationMapper orgMapper,
                                PlatformTransactionManager transactionManager) {
        this.parser = parser;
        this.mapper = mapper;
        this.orgMapper = orgMapper;
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    /**
     * 엑셀 파싱은 DB와 무관하므로 트랜잭션 밖에서 수행한다(SeedService와 동일한 이유).
     */
    public ReviewImportReport importFile(Long orgId, InputStream xlsx) {
        if (orgMapper.findById(orgId) == null) {
            throw new OrgNotFoundException("기관을 찾을 수 없습니다: " + orgId);
        }
        List<ReviewRow> rows = parser.parse(xlsx);
        return transactionTemplate.execute(status -> importRows(orgId, rows));
    }

    private ReviewImportReport importRows(Long orgId, List<ReviewRow> rows) {
        // 이미 DB에 있는 순번 + 이번 파일에서 먼저 처리된 순번을 모두 "이미 존재함"으로 취급한다
        // (SeedService.seedRows와 동일한 관례 - 같은 순번이 파일에 중복돼 있어도 두 번째는 갱신으로 집계).
        Set<Integer> seen = new HashSet<>(mapper.findSeqsByOrg(orgId));

        int created = 0;
        int updated = 0;
        for (ReviewRow row : rows) {
            if (seen.add(row.seq())) {
                created++;
            } else {
                updated++;
            }
            mapper.upsertFromFile(toReviewItem(orgId, row));
        }
        return new ReviewImportReport(created, updated, rows.size());
    }

    private ReviewItem toReviewItem(Long orgId, ReviewRow row) {
        ReviewItem item = new ReviewItem();
        item.setOrgId(orgId);
        item.setSeq(row.seq());
        item.setSiteName(row.siteName());
        item.setCategory(row.category());
        item.setBoardPath(row.boardPath());
        item.setBoardName(row.boardName());
        item.setPostTitle(row.postTitle());
        item.setUrl(row.url());
        item.setPostRegistered(row.postRegistered());
        item.setProducedDate(row.producedDate());
        item.setPublishedDate(row.publishedDate());
        item.setHasAttachment(row.hasAttachment());
        item.setKoglAttached(row.koglAttached());
        item.setKoglType(row.koglType());
        item.setAiType(row.aiType());
        item.setSurveyorNote(row.surveyorNote());
        item.setOpenable(row.openable());
        item.setReviewMajor(row.reviewMajor());
        item.setReviewMinor(row.reviewMinor());
        item.setReviewResult(row.reviewResult());
        item.setJudgedKoglType(row.judgedKoglType());
        item.setJudgedAiType(row.judgedAiType());
        item.setOpinion(row.opinion());
        item.setLawyerNote(row.lawyerNote());
        item.setNeedsProcessing(row.needsProcessing());
        return item;
    }
}
