package com.zioinfo.kintex.publicsite;

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

import java.util.List;
import java.util.Map;

/**
 * 공개 관람객 안내 매퍼 (V43 근거) — 전 조회 read-only, tenant_id='KINTEX' 고정.
 * <p>근거: v_event_calendar / v_event_monthly_summary / visitor_guide / transport_info.
 * <p>★ Map 반환 @Select 는 camelCase 별칭에 반드시 쌍따옴표({@code AS "x"})를 사용한다(PG lower-fold 방지).
 * <p>★ 외부 실시간 호출 없이 DB 만 서빙 — AI 관람 도우미의 유일한 근거 소스.
 */
@Mapper
public interface PublicGuideMapper {

    // ── 연/월 캘린더 (v_event_calendar) ──────────────────────────────────────
    /**
     * 연/월/생명주기 필터 캘린더 조회 — 시작일 오름차순(타임라인). 필터는 모두 선택.
     * lifecycle ∈ UPCOMING|ONGOING|ENDED (null 이면 전체).
     */
    @Select("""
            <script>
            SELECT id,
                   name,
                   category,
                   hall_label   AS "hallLabel",
                   poster_url   AS "posterUrl",
                   to_char(start_date, 'YYYY-MM-DD') AS "startDate",
                   to_char(end_date,   'YYYY-MM-DD') AS "endDate",
                   event_year   AS "eventYear",
                   event_month  AS "eventMonth",
                   lifecycle
            FROM v_event_calendar
            <where>
              tenant_id = 'KINTEX'
              <if test="year  != null"> AND event_year  = #{year}  </if>
              <if test="month != null"> AND event_month = #{month} </if>
              <if test="lifecycle != null and lifecycle != ''"> AND lifecycle = #{lifecycle} </if>
            </where>
            ORDER BY start_date ASC NULLS LAST, id
            LIMIT #{limit}
            </script>
            """)
    List<Map<String, Object>> findCalendar(@Param("year") Integer year,
                                           @Param("month") Integer month,
                                           @Param("lifecycle") String lifecycle,
                                           @Param("limit") int limit);

    /**
     * 행사명 부분검색 — AI 도우미 이름 매칭용. 미래 행사 우선(가까운 순) → 과거 최신순.
     * tokens 는 이름 ILIKE OR 결합(빈 리스트면 호출자가 스킵).
     */
    @Select("""
            <script>
            SELECT id,
                   name,
                   category,
                   hall_label   AS "hallLabel",
                   poster_url   AS "posterUrl",
                   to_char(start_date, 'YYYY-MM-DD') AS "startDate",
                   to_char(end_date,   'YYYY-MM-DD') AS "endDate",
                   event_year   AS "eventYear",
                   event_month  AS "eventMonth",
                   lifecycle
            FROM v_event_calendar
            WHERE tenant_id = 'KINTEX'
              AND (
                <foreach collection="tokens" item="t" separator=" OR ">
                  name ILIKE ('%' || #{t} || '%')
                </foreach>
              )
            ORDER BY (start_date >= CURRENT_DATE) DESC,
                     CASE WHEN start_date >= CURRENT_DATE THEN start_date END ASC NULLS LAST,
                     start_date DESC NULLS LAST,
                     id
            LIMIT #{limit}
            </script>
            """)
    List<Map<String, Object>> searchEventsByName(@Param("tokens") List<String> tokens,
                                                 @Param("limit") int limit);

    // ── 월별 집계 (v_event_monthly_summary) ─────────────────────────────────
    /** 연도(선택) 월별 전시 건수 집계 — 연/월 오름차순. */
    @Select("""
            <script>
            SELECT event_year  AS "eventYear",
                   event_month AS "eventMonth",
                   event_count AS "eventCount"
            FROM v_event_monthly_summary
            <where>
              tenant_id = 'KINTEX'
              <if test="year != null"> AND event_year = #{year} </if>
            </where>
            ORDER BY event_year, event_month
            </script>
            """)
    List<Map<String, Object>> findMonthlySummary(@Param("year") Integer year);

    // ── 방문가이드 (visitor_guide) ───────────────────────────────────────────
    /** 카테고리(선택) 방문가이드 — use_yn='Y' 만. 카테고리·표시순 정렬. */
    @Select("""
            <script>
            SELECT id,
                   category,
                   title,
                   body,
                   summary,
                   display_order AS "displayOrder",
                   source_url    AS "sourceUrl"
            FROM visitor_guide
            <where>
              tenant_id = 'KINTEX' AND use_yn = 'Y'
              <if test="category != null and category != ''"> AND category = #{category} </if>
            </where>
            ORDER BY category, display_order, id
            </script>
            """)
    List<Map<String, Object>> findGuides(@Param("category") String category);

    // ── 교통수단 (transport_info) ────────────────────────────────────────────
    /** 교통수단(선택 mode) 구조화 목록 — 표시순 정렬. */
    @Select("""
            <script>
            SELECT id,
                   mode,
                   line_name     AS "lineName",
                   route,
                   from_point    AS "fromPoint",
                   travel_time   AS "travelTime",
                   note,
                   display_order AS "displayOrder",
                   source_url    AS "sourceUrl"
            FROM transport_info
            <where>
              tenant_id = 'KINTEX'
              <if test="mode != null and mode != ''"> AND mode = #{mode} </if>
            </where>
            ORDER BY display_order, mode, id
            </script>
            """)
    List<Map<String, Object>> findTransport(@Param("mode") String mode);
}
