package com.zioinfo.kintex.parking;

import org.apache.ibatis.annotations.Insert;
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;

/**
 * 주차 도메인 매퍼 — 주차장 마스터 read-only + 주차권 발급/조회. tenant_id='KINTEX' 고정.
 * <p>★ Map 반환 @Select 는 camelCase 별칭에 반드시 쌍따옴표({@code AS "x"})를 사용한다(PG lower-fold 방지).
 * <p>실시간 점유는 DB에 없다 — {@link SimulatedParkingService} 시뮬레이션 어댑터가 산출(외부 미연동).
 */
@Mapper
public interface ParkingMapper {

    /** 활성 주차장 마스터 목록 — 표시순. */
    @Select("""
            SELECT id             AS "lotId",
                   code,
                   name,
                   exhibition_center AS "exhibitionCenter",
                   total_capacity  AS "totalCapacity",
                   hourly_rate     AS "hourlyRate",
                   daily_max       AS "dailyMax",
                   pass_price      AS "passPrice",
                   note,
                   sort_order      AS "sortOrder"
            FROM parking_lot
            WHERE tenant_id = 'KINTEX' AND status = 'active'
            ORDER BY sort_order, id
            """)
    List<Map<String, Object>> findActiveLots();

    /** 단일 주차장(구매 검증용). 없으면 null. */
    @Select("""
            SELECT id             AS "lotId",
                   code,
                   name,
                   pass_price      AS "passPrice",
                   status
            FROM parking_lot
            WHERE tenant_id = 'KINTEX' AND id = #{lotId}
            """)
    Map<String, Object> findLot(@Param("lotId") String lotId);

    /**
     * 특정 주차장·이용일의 유효(PAID/USED) 사전 주차권 수 — 시뮬레이션 점유 가중치.
     * 사전 예약분이 실시간 잔여에 반영되도록 한다.
     */
    @Select("""
            SELECT count(*)
            FROM parking_pass
            WHERE tenant_id = 'KINTEX'
              AND lot_id = #{lotId}
              AND use_date = CAST(#{useDate} AS date)
              AND status IN ('PAID', 'USED')
            """)
    long countActivePasses(@Param("lotId") String lotId, @Param("useDate") String useDate);

    /** 주차권 발급 저장. */
    @Insert("""
            INSERT INTO parking_pass
                (tenant_id, id, pass_no, event_id, lot_id, lot_name, user_id, use_date,
                 vehicle_plate_masked, amount, status, pay_method, pay_approval_no)
            VALUES
                ('KINTEX', #{id}, #{passNo}, #{eventId}, #{lotId}, #{lotName}, #{userId},
                 CAST(#{useDate} AS date), #{vehiclePlateMasked}, #{amount}, #{status},
                 #{payMethod}, #{payApprovalNo})
            """)
    void insertPass(Map<String, Object> pass);

    /** 발급번호 중복 확인(유니크 보증). */
    @Select("SELECT count(*) FROM parking_pass WHERE pass_no = #{passNo}")
    long countPassNo(@Param("passNo") String passNo);

    /** 내 주차권 목록 — 소유자 본인만. 이용일 최신순. */
    @Select("""
            SELECT pass_no        AS "passNo",
                   status,
                   lot_id         AS "lotId",
                   lot_name       AS "lotName",
                   event_id       AS "eventId",
                   to_char(use_date, 'YYYY-MM-DD') AS "useDate",
                   vehicle_plate_masked AS "vehiclePlateMasked",
                   amount,
                   pay_method     AS "payMethod",
                   pay_approval_no AS "payApprovalNo",
                   to_char(created_at, 'YYYY-MM-DD"T"HH24:MI:SS') AS "issuedAt"
            FROM parking_pass
            WHERE tenant_id = 'KINTEX' AND user_id = #{userId}
            ORDER BY use_date DESC, created_at DESC
            """)
    List<Map<String, Object>> findPassesByUser(@Param("userId") String userId);
}
