package kr.itn.itnhub.process;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 권리처리 매퍼.
 *
 * <p>어느 값이 "처리완료"인지는 쿼리에 박지 않고 {@code doneStatus} 파라미터로 받는다.
 * 코드값은 코드표에서 오는데 SQL 안에는 코드표를 참조할 방법이 마땅치 않아, 서비스가
 * 읽어 넘긴다. 이 값이 틀리면 진행률과 처리일시가 조용히 어긋나므로 항상 함께 넘겨야 한다.</p>
 */
@Mapper
public interface ProcessItemMapper {

    /**
     * 순번 오름차순, keyword는 사이트명/게시물제목 LIKE. status는 null=전체,
     * "DONE"=처리완료, "PENDING"=그 외(null/빈/미처리)만.
     */
    List<ProcessItem> findPage(@Param("orgId") Long orgId, @Param("keyword") String keyword,
                                @Param("site") String site, @Param("board") String board,
                                @Param("title") String title,
                                @Param("status") String status,
                                @Param("doneStatus") String doneStatus,
                                @Param("offset") int offset,
                                @Param("limit") int limit);

    /** keyword/status로 필터링된 건수 - 필터별 페이지 경계 계산용(현재 응답의 total과는 별개). */
    int countByOrg(@Param("orgId") Long orgId, @Param("keyword") String keyword,
                   @Param("site") String site, @Param("board") String board,
                   @Param("title") String title, @Param("status") String status,
                   @Param("doneStatus") String doneStatus);

    /** 여러 건에 같은 값을 한 번에 반영한다(일괄 등록). null 항목은 기존 값을 유지한다. */
    int updateProcessingBulk(@Param("orgId") Long orgId, @Param("ids") List<Long> ids,
                             @Param("processStatus") String processStatus,
                             @Param("judgedKoglType") String judgedKoglType,
                             @Param("finalOpinion") String finalOpinion,
                             @Param("doneStatus") String doneStatus);

    /** 일괄 삭제. */
    int deleteByIds(@Param("orgId") Long orgId, @Param("ids") List<Long> ids);

    /** 다운로드/재업로드 판정용으로 페이징 없이 순번순 전체를 읽는다. */
    List<ProcessItem> findAllByOrg(@Param("orgId") Long orgId);

    /** 이미 저장된 순번 전체 - ImportService가 신규/갱신 집계를 메모리에서 판단하기 위함. */
    List<Integer> findSeqsByOrg(@Param("orgId") Long orgId);

    ProcessItem findById(@Param("orgId") Long orgId, @Param("id") Long id);

    /**
     * 엑셀 재업로드 1행 반영. (org_id, seq) 충돌 시 조사원+권리확인 영역(계약서 유무 제외)은
     * 항상 덮어쓰고, 계약서 유무와 권리처리 영역은 web_edited_at이 null일 때만 덮어쓴다 -
     * 정책 세부는 XML 주석 참고.
     */
    int upsertFromFile(ProcessItem item);

    /** 권리처리 상세의 [처리등록]/[수정] 저장. web_edited_at을 찍고, 처리완료 최초 도달 시각을 processed_at에 남긴다. */
    int updateProcessing(@Param("orgId") Long orgId, @Param("id") Long id,
                          @Param("contractDocs") String contractDocs,
                          @Param("judgedKoglType") String judgedKoglType,
                          @Param("judgedAiType") String judgedAiType,
                          @Param("finalOpinion") String finalOpinion,
                          @Param("judgmentBasis") String judgmentBasis,
                          @Param("processStatus") String processStatus,
                          @Param("doneStatus") String doneStatus);

    int deleteById(@Param("orgId") Long orgId, @Param("id") Long id);

    /** 기관 삭제 캐스케이드 외에는 아직 쓰이지 않지만, 저장 비용이 낮아 함께 둔다(review_item과 동일 관례). */
    int deleteByOrg(@Param("orgId") Long orgId);

    /** 검색어/상태 필터와 무관한 기관 전체 진행률 - 목록 헤더와 기관 상세 통계 카드가 함께 쓴다. */
    ProcessStats stats(@Param("orgId") Long orgId, @Param("doneStatus") String doneStatus);
}
