<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zioinfo.mall.member.mapper.MemberMapper">
  <select id="findByUsername" resultType="com.zioinfo.mall.member.MallMember">
    SELECT * FROM mall_member WHERE username = #{username}
  </select>
  <insert id="upsert" parameterType="com.zioinfo.mall.member.MallMember">
    INSERT INTO mall_member (username, display_name, email, phone, default_zip, default_address, crm_customer_key, tier)
    VALUES (#{username}, #{displayName}, #{email}, #{phone}, #{defaultZip}, #{defaultAddress}, #{crmCustomerKey}, COALESCE(#{tier},'STANDARD'))
    ON CONFLICT (username) DO UPDATE SET
      display_name = EXCLUDED.display_name, email = EXCLUDED.email, phone = EXCLUDED.phone,
      default_zip = EXCLUDED.default_zip, default_address = EXCLUDED.default_address
  </insert>

  <!--
    관리자 회원 목록 — PII 비노출.
    email/phone 은 SQL 레벨에서 마스킹(앞 2자 + *** + 도메인 / 끝 4자리만). 상세 주소는 미선택.
    주문수/누적결제액은 mall_order 를 owner(=username) 로 LEFT JOIN 집계.
  -->
  <sql id="adminWhere">
    <where>
      <if test="keyword != null and keyword != ''">
        AND (m.username ILIKE '%' || #{keyword} || '%' OR m.display_name ILIKE '%' || #{keyword} || '%')
      </if>
      <if test="tier != null and tier != ''">AND m.tier = #{tier}</if>
    </where>
  </sql>

  <select id="adminList" resultType="com.zioinfo.mall.member.MallMemberSummary">
    SELECT
      m.id, m.username, m.display_name AS displayName,
      CASE WHEN m.email IS NULL OR m.email = '' THEN NULL
           WHEN POSITION('@' IN m.email) > 2
             THEN SUBSTRING(m.email FROM 1 FOR 2) || '***' || SUBSTRING(m.email FROM POSITION('@' IN m.email))
           ELSE '***' || SUBSTRING(m.email FROM POSITION('@' IN m.email)) END AS emailMasked,
      CASE WHEN m.phone IS NULL OR LENGTH(m.phone) &lt; 4 THEN NULL
           ELSE '***-****-' || SUBSTRING(m.phone FROM LENGTH(m.phone) - 3) END AS phoneMasked,
      m.default_zip AS defaultZip, m.tier, m.created_at AS createdAt,
      COALESCE(o.order_count, 0) AS orderCount,
      COALESCE(o.total_spent, 0) AS totalSpent
    FROM mall_member m
    LEFT JOIN (
      SELECT owner, COUNT(*) AS order_count, SUM(COALESCE(pay_amount, total_amount, 0)) AS total_spent
      FROM mall_order WHERE status NOT IN ('CANCELLED','REFUNDED','FAILED') GROUP BY owner
    ) o ON o.owner = m.username
    <include refid="adminWhere"/>
    ORDER BY m.created_at DESC
    LIMIT #{limit}
  </select>

  <select id="countAdminList" resultType="int">
    SELECT COUNT(*) FROM mall_member m <include refid="adminWhere"/>
  </select>
</mapper>
