package com.zioinfo.kintex.ticket.smart;

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

import java.util.Map;

/**
 * F-B1 스마트티켓(회전 QR) 매퍼 — 주문·발권 대조 + 디바이스 바인딩 upsert/조회.
 * <p>★ camelCase 별칭은 반드시 쌍따옴표({@code AS "x"})(PG lower-fold 방지).
 * <p>보안(§0-3): device_hash·secret 는 서버 전용. 조회 응답에 secret 을 노출하지 않는다(서비스가 통제).
 */
@Mapper
public interface SmartTicketMapper {

    /** 주문번호 + 연락처 해시 대조 → 주문 id(둘 다 일치해야). 없으면 null. */
    @Select("""
            SELECT id AS "orderId"
            FROM ticket_order
            WHERE order_no = #{orderNo} AND buyer_contact_hash = #{contactHash}
            LIMIT 1
            """)
    Map<String, Object> findOrderIdForLookup(@Param("orderNo") String orderNo,
                                             @Param("contactHash") String contactHash);

    /** 발권 티켓이 해당 주문 소속인지(대조). 1이면 소속. */
    @Select("""
            SELECT count(*)
            FROM ticket_issue
            WHERE tenant_id = 'KINTEX' AND order_id = #{orderId} AND ticket_code = #{ticketCode}
            """)
    int ticketBelongsToOrder(@Param("orderId") String orderId, @Param("ticketCode") String ticketCode);

    /** 바인딩 upsert — 디바이스 재바인딩(기기 변경) 허용, secret 재발급으로 이전 기기 토큰 무효화. */
    @Update("""
            INSERT INTO ticket_smart_binding (tenant_id, ticket_code, device_hash, secret)
            VALUES ('KINTEX', #{ticketCode}, #{deviceHash}, #{secret})
            ON CONFLICT (tenant_id, ticket_code)
            DO UPDATE SET device_hash = EXCLUDED.device_hash,
                          secret      = EXCLUDED.secret,
                          bound_at    = now()
            """)
    void upsertBinding(@Param("ticketCode") String ticketCode,
                       @Param("deviceHash") String deviceHash,
                       @Param("secret") String secret);

    /** 바인딩 조회(서비스 전용 — secret 포함). 없으면 null. */
    @Select("""
            SELECT ticket_code  AS "ticketCode",
                   device_hash  AS "deviceHash",
                   secret       AS "secret"
            FROM ticket_smart_binding
            WHERE tenant_id = 'KINTEX' AND ticket_code = #{ticketCode}
            """)
    Map<String, Object> findBinding(@Param("ticketCode") String ticketCode);

    /** 검증 시 사용 마킹(감사). */
    @Update("UPDATE ticket_smart_binding SET last_used_at = now() WHERE tenant_id='KINTEX' AND ticket_code = #{ticketCode}")
    void markUsed(@Param("ticketCode") String ticketCode);
}
