<script setup lang="ts">
import {
  globalDateFormat,
  getTime,
  fromUnixTime,
  addMonths,
  differenceInDays,
} from '@seed-next/date'
import { getComponentGroup } from '#layers/utils/dataUtil'
import {
  COUPON_NO_LENGTH_LIMIT,
  COUPON_RESULT,
} from '#layers/types/api/couponData'
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
import type { ReqCouponList } from '#layers/types/api/couponData'

interface Props {
  id?: string
  components: PageDataTemplateComponents
  pageVerTmplSeq: number
  pageVerTmplNameEn: string
}
const props = defineProps<Props>()

const runtimeConfig = useRuntimeConfig()

const stoveApiUrl = runtimeConfig.public.stoveApiUrl as string
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl as string
const multilingualFileName = 'STOVE_PUBTEMPLATE_homepage_brand_coupon.json'

// Multilingual
const resultGetMultilingual = await useGetMultilingual({
  baseApiUrl: dataResourcesUrl,
  fileName: multilingualFileName,
})
const { t, tm, locale }: any = useI18n({
  useScope: 'local',
  messages: Object(resultGetMultilingual?.value?.multilingual),
})

// Composables
const { sendLog } = useAnalytics()
// const { isGameMaintenance, checkGameMaintenance } = useGetGameMaintenance()
const { isWebInspection, getInspectionDataExternal } =
  useGetInspectionDataExternal()
const breakpoints = useResponsiveBreakpoints()
const { handleTokenValidation } = useTokenValidation()
const { hasGuid, characterList, getGuid, getCharacterList } =
  useGameLinkedData()
const {
  couponList,
  hasNoCouponList,
  totalCount,
  postCouponUse,
  getCouponList,
} = useCoupon()
const {
  startDate,
  endDate,
  currentSearchPeriod,
  searchStatus,
  setCouponDate,
  toUnixTimestamp,
} = useCouponDate()
const { pageNo, pageSize, updatePagination, getPageBlock } = useCouponPaging()

// Store
const gameDataStore = useGameDataStore()
const modalStore = useModalStore()
const couponStore = useCouponStore()
const { gameData } = storeToRefs(gameDataStore)
const { handleOpenAlert, handleOpenConfirm } = modalStore
const { couponNo, isSelectCharacter, selectCharacter } =
  storeToRefs(couponStore)
const { updateCouponNo, updateSelectCharacter, isEmptyCouponNo } = couponStore

// Refs
const clientIp = ref('')
const monthSelectList = ref<Array<number>>([1, 3, 6, 12])
const isSelectCharacterModalOpen = ref(false)

// Computed
const backgroundData = computed(() =>
  getComponentGroup(props.components, 'background')
)
const sortedCharacterList = computed(() => {
  return characterList.value
    .map(characterInfo => {
      const worldId =
        characterInfo.world_id.split('_')[
          characterInfo.world_id?.split('_').length - 1
        ]
      const arrWorldIdPriority = ['global', 'asia']
      const sortedIndex = arrWorldIdPriority.indexOf(worldId)
      return { ...characterInfo, sortedIndex }
    })
    .sort((a, b) => {
      return a.sortedIndex !== b.sortedIndex ? a.sortedIndex - b.sortedIndex : 0
    })
})

// Functions
const handleSendLog = (item: string) => {
  const analytics = {
    action_type: 'click',
    click_item: item,
    click_sarea: props.pageVerTmplNameEn,
  }

  sendLog(locale.value, analytics)
}
/**
 * @description 기본 Alert 모달 팝업 함수입니다.
 * @param text - 모달 내용
 */
const openAlert = (text: string) => {
  handleOpenAlert({
    contentText: text,
    isOutsideClose: true,
  })
}

/**
 * @description 유저 IP 조회 함수입니다.
 */
const getClientIp = async () => {
  if (!clientIp.value) {
    try {
      const ipData = await $fetch('/api/clientIp')
      clientIp.value = ipData || ''
    } catch (e) {
      console.error('[Exception] FxCoupon01.getClientIp:', e)
      clientIp.value = ''
    }
  } // 이미 조회했으면 재사용
  return clientIp.value
}

/**
 * @description 쿠폰 사용 전 유효성 체크 함수입니다.
 * @returns {number} 쿠폰 사용 전 유효성 체크 결과
 */
const validationCheckBefore = async () => {
  // FIXME: 다른 체크 로직 추가 시 주석 해제 필요 ---------------------------------------------------

  /**
   * @description 게임 점검 체크하는 로직입니다.
   * await checkGameMaintenance({
   *   baseApiUrl: stoveMaintenanceApiUrl,
   *   category: 'GAME',
   *   service_id1: gameData.value.game_id,
   *   gameId: gameData.value.game_id,
   *   lang: locale.value,
   * })
   * if (isGameMaintenance.value) {
   *   return COUPON_RESULT.GAME_MAINTENANCE
   * }
   */

  /**
   * @description 언어 코드 존재 여부 체크하는 로직입니다.
   * if (locale.value == null || locale.value === '') {
   *   return COUPON_RESULT.SYSTEM_ERROR
   * }
   */

  /**
   * @description 서버(캐릭터) 선택 여부 체크하는 로직입니다.
   * if (!isSelectCharacter.value) {
   *   return COUPON_RESULT.SELECT_CHARACTER_REQUIRED
   * }
   */

  /**
   * @description 선택한 캐릭터 정보 유효 여부 (접속 계정과 동일한 캐릭터 여부) 체크하는 로직입니다.
   * await getCharacterList({
   *   baseApiUrl: stoveApiUrl,
   *   accessToken: csrGetAccessToken(),
   *   game_id: gameData.value.game_id,
   *   gameId: gameData.value.game_id,
   * })
   * if (
   *   !characterList.value.some(
   *     character => character.character_id === selectCharacter.value.character_id
   *   )
   * ) {
   *   return COUPON_RESULT.SELECT_CHARACTER_REQUIRED
   * }
   */

  // ------------------------------------------------------------------------

  /**
   * @description 웹 점검 여부 체크
   */
  await getInspectionDataExternal({
    baseApiUrl: stoveApiUrl,
    gameId: gameData.value.game_id,
  })
  if (isWebInspection.value) {
    return COUPON_RESULT.WEB_INSPECTION
  }

  /**
   * @description 로그인 여부 체크
   */
  const accessToken = csrGetAccessToken()
  const validateTokenResult = await handleTokenValidation(accessToken || '')
  if (validateTokenResult === false) {
    return COUPON_RESULT.LOGIN_REQUIRED
  }

  /**
   * @description GUID(게임 이용 동의) 체크
   */
  await getGuid({
    baseApiUrl: stoveApiUrl,
    accessToken: csrGetAccessToken(),
    game_id: gameData.value.game_id,
    gameId: gameData.value.game_id,
  })
  if (!hasGuid.value) {
    return COUPON_RESULT.EMPTY_GUID
  }

  /**
   * @description 쿠폰번호 입력 여부 체크
   */
  if (isEmptyCouponNo(couponNo.value)) {
    return COUPON_RESULT.NULL_COUPON_NO
  }

  /**
   * @description 쿠폰번호 유효성 체크 (최소 2자, 최대 20자)
   */
  if (
    !isInRange(
      couponNo.value.length,
      COUPON_NO_LENGTH_LIMIT.MIN,
      COUPON_NO_LENGTH_LIMIT.MAX
    )
  ) {
    return COUPON_RESULT.FAIL_COUPON_FORMAT
  }

  return 0
}

/**
 * @description 쿠폰 등록 버튼 함수입니다.
 * @description FE 유효성 체크 후 캐릭터 선택 모달 팝업 노출합니다.
 */
const handleCouponUse = async () => {
  handleSendLog(t('Coupon_Registration', {}, { locale: 'ko' }))

  const validationCheckBeforeResult = await validationCheckBefore()

  if (validationCheckBeforeResult !== 0) {
    if (validationCheckBeforeResult === COUPON_RESULT.LOGIN_REQUIRED) {
      // 미로그인일 경우 : 이미 validationCheckBefore 함수에서 로그인 모달 팝업 노출했으므로 추가 처리 필요 없음
      return
    } else if (
      validationCheckBeforeResult === COUPON_RESULT.SELECT_CHARACTER_REQUIRED
    ) {
      // 캐릭터 미선택일 경우 : 캐릭터 선택 모달 팝업 노출
      openSelectCharacterModal()
      return
    } else if (validationCheckBeforeResult === COUPON_RESULT.SYSTEM_ERROR) {
      // 시스템 에러일 경우 : 에러 팝업 노출 (에러코드)
      openAlert(t('Coupon_Error', { code: validationCheckBeforeResult }))
      return
    } else {
      // 그 외 오류 팝업 노출
      openAlert(tm(`Coupon_Alert_(${validationCheckBeforeResult})`))
      return
    }
  } else {
    openSelectCharacterModal()
  }
}

/**
 * @description 캐릭터 선택 후, 확인 버튼 클릭 시 쿠폰 등록 API 호출 함수입니다.
 */
const handleCouponRegister = async () => {
  handleSendLog('캐릭터 선택 완료')
  closeSelectCharacterModal()

  const validationCheckBeforeResult = await validationCheckBefore()
  if (validationCheckBeforeResult !== 0) {
    if (validationCheckBeforeResult === COUPON_RESULT.LOGIN_REQUIRED) {
      // 미로그인일 경우 : 이미 validationCheckBefore 함수에서 로그인 모달 팝업 노출했으므로 추가 처리 필요 없음
      return
    } else if (
      validationCheckBeforeResult === COUPON_RESULT.SELECT_CHARACTER_REQUIRED
    ) {
      // 캐릭터 미선택일 경우 : 캐릭터 선택 모달 팝업 노출
      openSelectCharacterModal()
      return
    } else if (validationCheckBeforeResult === COUPON_RESULT.SYSTEM_ERROR) {
      // 시스템 에러일 경우 : 에러 팝업 노출 (에러코드)
      openAlert(t('Coupon_Error', { code: validationCheckBeforeResult }))
      return
    } else {
      // 그 외 오류 팝업 노출
      openAlert(tm(`Coupon_Alert_(${validationCheckBeforeResult})`))
      return
    }
  } else {
    await getClientIp()
    const res = await postCouponUse({
      accessToken: csrGetAccessToken(),
      user_token_type: 'web',
      game_code: gameData.value.game_code.toString(),
      coupon_no: couponNo.value,
      client_ipaddr: clientIp.value,
      world_no: selectCharacter.value.world_id,
      character_no: `${selectCharacter.value.character_id}`,
      lang_code: locale.value,
    })
    if (res.code === 0) {
      openAlert(tm('Coupon_Alert_Success'))
    } else {
      openAlert(tm(`Coupon_Alert_(${res.code})`))
    }
  }
}

/**
 * @description 기간 선택 이벤트 함수입니다.
 * @param {number} month - 선택한 기간 개월수
 */
const handlePeriodSelect = (month: number) => {
  const today = new Date()
  const startTimestamp = toUnixTimestamp(today, 'start')
  const endTimestamp = toUnixTimestamp(today, 'end')

  const newStartDate = addMonths(fromUnixTime(startTimestamp), -month)
  const newEndDate = fromUnixTime(endTimestamp)

  setCouponDate(newStartDate, 'start')
  setCouponDate(newEndDate, 'end')
  handleSendLog(t(`Coupon_Month${month}`, {}, { locale: 'ko' }))
}

/**
 * @description 조회하기 이벤트 함수입니다.
 */
const handlePeriodSearch = async () => {
  if (!startDate.value || !endDate.value) {
    return
  }

  handleSendLog(t('Coupon_Search', {}, { locale: 'ko' }))

  const accessToken = csrGetAccessToken()
  const validateTokenResult = await handleTokenValidation(accessToken || '')
  if (validateTokenResult === false) {
    return
  }

  const result = differenceInDays(endDate.value, startDate.value)
  if (result < 0 || result > 365) {
    openAlert(tm('Coupon_Alert_OverDays'))
    return
  }

  const req: ReqCouponList = {
    accessToken: accessToken,
    user_token_type: 'web',
    game_code: gameData.value.game_code.toString(),
    start_date: getTime(startDate.value),
    end_date: getTime(endDate.value),
    use_state_code: searchStatus.value,
    page_size: pageSize.value,
    page_no: pageNo.value,
    lang_code: locale.value,
  }

  await getCouponList(req)
}

/**
 * @desciprion 페이지 변경 이벤트 함수입니다.
 * @param {number} newPageNo
 */
const handlePaging = async (newPageNo: number) => {
  updatePagination(newPageNo)
  await handlePeriodSearch()
}

/**
 * @description 게임별 스토브 쿠폰함 URL 조회 함수입니다.
 * @returns {string} 게임별 스토브 쿠폰함 URL
 */
const getCouponBoxUrl = () => {
  let url = ''

  if (breakpoints.value.isMobile) {
    url = getStoveCouponUrl('mobile')
  } else {
    url = getStoveCouponUrl('desktop')
  }

  return `${url}?game_id=${gameData.value.game_id}`
}

/**
 * @description @coupon{문구} 형식의 문구를 게임별 스토브 쿠폰함 URL의 a태그로 변환합니다.
 * @param {string} text - 변환할 문구
 * @returns {string} 변환된 문구 HTML
 * @description string으로 return하므로 v-dompurify-html 사용 필요
 */
const getKeyToCouponUrl = (text: string) => {
  const couponBoxUrl = getCouponBoxUrl()

  let result = ''

  if (text.includes('@coupon')) {
    result = text.replace(/@coupon\{(.*?)\}/g, (_, key) => {
      return `<a href="${couponBoxUrl}" rel="noopener noreferrer" target="_blank" class="text-[#3C75FF] underline decoration-solid decoration-auto underline-offset-2 after:content-[''] after:absolute after:top-1/2 after:left-0 after:translate-y-[-50%] after:w-full after:h-fuill after:bg-white after:opacity-0 transition-opacity duration-300 ease-in-out hover:after:opacity-20">${key}</a>`
    })

    return result
  } else {
    return text
  }
}

/**
 * @description STOVE 쿠폰함으로 이동합니다.
 */
const goToCouponBox = () => {
  let url = ''

  if (breakpoints.value.isMobile) {
    url = getStoveCouponUrl('mobile')
  } else {
    url = getStoveCouponUrl('desktop')
  }

  csrGoExternalLink(`${url}?game_id=${gameData.value.game_id}`)
}

/**
 * @description 쿠폰 등록 내역의 사용하기 버튼의 클릭 이벤트 함수입니다.
 */
const handleGoToCouponBox = async () => {
  handleSendLog(t('Coupon_Item_Use', {}, { locale: 'ko' }))

  const accessToken = csrGetAccessToken()
  const validateTokenResult = await handleTokenValidation(accessToken || '')

  // 미로그인 상태일 경우 Return
  if (validateTokenResult === false) {
    return
  }

  // 로그인 상태일 경우 모달 표시
  handleOpenConfirm({
    contentText: tm('Coupon_Alert_StoveCouponBox'),
    confirmButtonText: tm('Coupon_StoveCouponBox'),
    modalName: 'modal-coupon-use',
    confirmButtonEvent: () => {
      goToCouponBox()
    },
  })
}

/**
 * @description 쿠폰 등록 관련 데이터를 초기화합니다.
 */
const initCouponData = () => {
  updateSelectCharacter(null)
  updateCouponNo('')
  updatePagination(1)
}

/**
 * @description 캐릭터 선택 모달 팝업 열기
 */
const openSelectCharacterModal = () => {
  isSelectCharacterModalOpen.value = true
}
/**
 * @description 캐릭터 선택 모달 팝업 닫기
 */
const closeSelectCharacterModal = () => {
  isSelectCharacterModalOpen.value = false
}

onMounted(async () => {
  initCouponData()

  const accessToken = csrGetAccessToken()
  if (accessToken) {
    handlePeriodSelect(1)
    await handlePeriodSearch()
  }
})
</script>

<template>
  <WidgetsFixMainTitle
    :id="props.id"
    :title="tm('Coupon_Page_Title')"
    :resources-data="backgroundData"
  />

  <div class="section-container static">
    <section class="section-static">
      <WidgetsFixSubTitle :title="tm('Coupon_Section_Registration_Title')" />

      <div
        class="relative flex flex-col items-center jutify-start w-full bg-white p-[20px] mt-[16px] rounded-[12px] sm:rounded-[16px] md:p-[32px] md:mt-[24px]"
      >
        <div
          class="relative flex flex-col items-center justify-start gap-[16px] w-full max-w-[880px] md:gap-[20px]"
        >
          <div
            novalidate
            class="relative flex flex-col items-center justify-start gap-[12px] w-full sm:flex-row"
          >
            <AtomsInput
              :model-value="couponNo"
              :name="tm('Coupon_Enter_Number')"
              :placeholder="tm('Coupon_Enter_Number_Please')"
              maxlength="20"
              @update:model-value="updateCouponNo"
            />
            <AtomsButton
              type="action"
              button-size="size-small"
              background-color="#383838"
              text-color="#FFFFFF"
              class="relative flex items-center justify-center w-full gap-[4px] px-0 sm:w-[143px] sm:shrink-0 md:h-[56px] md:text-[16px] md:leading-[24px] md:tracking-[-0.48px]"
              @click="handleCouponUse"
            >
              <span>{{ tm('Coupon_Registration') }}</span>
            </AtomsButton>
          </div>

          <ul class="relative flex flex-col items-start justify-start w-full">
            <template v-for="notice in tm('Coupon_Notice_List')" :key="notice">
              <li
                class="relative flex items-start justify-start w-full pl-[20px] before:content-[''] before:absolute before:top-[10px] before:left-[9px] before:w-[3px] before:h-[3px] before:rounded-full before:bg-[#666666] text-left text-[#666666] text-[13px] font-[400] leading-[22px] tracking-[-0.325px] md:text-[14px] md:leading-[24px] md:tracking-[-0.42px] md:before:left-[8px] md:before:w-[4px] md:before:h-[4px]"
              >
                <span
                  v-dompurify-html="
                    getKeyToCouponUrl(tm(notice as string) as string)
                  "
                ></span>
              </li>
            </template>
          </ul>
        </div>
      </div>
    </section>

    <section class="section-static">
      <WidgetsFixSubTitle
        :title="tm('Coupon_Section_History_Title')"
        class="flex-col"
      >
        <div
          class="relative flex flex-col items-start justify-start gap-[12px] w-full mt-[4px] md:gap-[16px] md:mt-[0] lg:flex-row lg:items-end lg:justify-between lg:gap-[0]"
        >
          <div
            class="relative flex items-center justify-start gap-[20px] w-full lg:w-auto lg:mr-auto"
          >
            <div
              v-if="breakpoints.isMd || breakpoints.isDesktop"
              class="relative flex items-center justify-start"
            >
              <template v-for="month in monthSelectList" :key="month">
                <AtomsButton
                  type="action"
                  button-size="size-small"
                  background-color="#FAFAFA"
                  text-color="#CCCCCC"
                  :class="[
                    'btn-period',
                    { 'btn-period-active': currentSearchPeriod === month },
                  ]"
                  @click="handlePeriodSelect(month)"
                >
                  <span>{{ tm(`Coupon_Month${month}`) }}</span>
                </AtomsButton>
              </template>
            </div>

            <div
              class="relative flex items-center justify-center gap-[8px] w-full md:w-auto"
            >
              <div
                class="relative flex items-center justify-center gap-[4px] md:gap-[8px] w-full md:w-auto"
              >
                <BlocksDatePicker
                  :key="getTime(startDate)"
                  :date="startDate"
                  @update:date="
                    (date: string) => setCouponDate(new Date(date), 'start')
                  "
                />
                <span
                  class="relative inline-flex items-center justify-center shrink-0 text-[#868078] text-[16px] font-[500] leading-[24px] tracking-[-0.48px] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px]"
                >
                  ~
                </span>
                <BlocksDatePicker
                  :key="getTime(endDate)"
                  :date="endDate"
                  @update:date="
                    (date: string) => setCouponDate(new Date(date), 'end')
                  "
                />
              </div>
              <AtomsButton
                type="action"
                button-size="size-small"
                background-color="#383838"
                text-color="#FFFFFF"
                class="shrink-0 w-[40px] h-[40px] p-0 md:w-auto md:px-[22px]"
                @click="handlePeriodSearch"
              >
                <span
                  class="relative flex items-center justify-center gap-[2px]"
                >
                  <span v-if="breakpoints.isMd || breakpoints.isDesktop">
                    {{ tm('Coupon_Search') }}
                  </span>
                  <AtomsIconsSearchLine :size="16" color="#FFFFFF" />
                </span>
              </AtomsButton>
            </div>
          </div>
          <p
            class="text-[#666666] text-[13px] font-[400] leading-[22px] tracking-[-0.325px] md:text-[14px] md:leading-[24px] md:tracking-[-0.421px]"
          >
            {{ tm('Coupon_Section_History_Description') }}
          </p>
        </div>
      </WidgetsFixSubTitle>

      <div
        class="relative w-full border border-solid border-[#D9D9D9] rounded-[12px] overflow-hidden sm:rounded-[16px]"
      >
        <table>
          <thead>
            <tr>
              <th class="w-auto !border-l-[0]">
                {{ tm('Coupon_Item_Name') }}
              </th>
              <th
                v-if="breakpoints.isMd || breakpoints.isDesktop"
                class="w-[260px]"
              >
                {{ tm('Coupon_Item_RegistDate') }}
              </th>
              <th class="w-[1%] whitespace-nowrap">
                {{ tm('Coupon_Item_Status') }}
              </th>
            </tr>
          </thead>
          <tbody>
            <template v-if="hasNoCouponList">
              <tr>
                <td
                  :colspan="
                    breakpoints.isMd || breakpoints.isDesktop ? '3' : '2'
                  "
                  class="!border-l-[0] !border-b-[0]"
                >
                  <p>{{ tm('Coupon_Has_Not_Item') }}</p>
                </td>
              </tr>
            </template>
            <template v-else>
              <template
                v-for="(coupon, couponIdx) in couponList"
                :key="coupon.coupon_box_id"
              >
                <tr>
                  <td
                    class="w-auto"
                    :class="
                      couponIdx === couponList.length - 1
                        ? '!border-l-[0] !border-b-[0]'
                        : '!border-l-[0]'
                    "
                  >
                    <p>{{ coupon.coupon_name }}</p>
                  </td>
                  <td
                    v-if="breakpoints.isMd || breakpoints.isDesktop"
                    :class="
                      couponIdx === couponList.length - 1
                        ? 'w-[260px] !border-b-[0]'
                        : 'w-[260px]'
                    "
                  >
                    <p>
                      {{
                        globalDateFormat(new Date(coupon.register_date), locale)
                      }}
                    </p>
                  </td>
                  <td
                    :class="
                      couponIdx === couponList.length - 1
                        ? '!px-[16px] md:!px-[20px] w-[1%] whitespace-nowrap !border-b-[0]'
                        : '!px-[16px] md:!px-[20px] w-[1%] whitespace-nowrap'
                    "
                  >
                    <template
                      v-if="
                        coupon.use_state === 1 &&
                        coupon.reward_type_code.includes(2)
                      "
                    >
                      <AtomsButton
                        type="action"
                        button-size="size-small"
                        background-color="transparent"
                        text-color="transparent"
                        class="coupon-item coupon-item-use"
                        @click="handleGoToCouponBox"
                      >
                        <span>{{ tm('Coupon_Item_Use') }}</span>
                      </AtomsButton>
                    </template>
                    <template v-else-if="coupon.use_state === 1">
                      <span class="coupon-item coupon-item-not-used">
                        {{ tm('Coupon_Item_Not_Used') }}
                      </span>
                    </template>
                    <template v-else-if="coupon.use_state === 2">
                      <span class="coupon-item coupon-item-used">
                        {{ tm('Coupon_Item_Used') }}
                      </span>
                    </template>
                    <template v-else-if="coupon.use_state === 4">
                      <span class="coupon-item coupon-item-expires">
                        {{ tm('Coupon_Item_Expires') }}
                      </span>
                    </template>
                    <template v-else-if="coupon.use_state === 6">
                      <span class="coupon-item coupon-item-deadline">
                        {{ tm('Coupon_Item_Deadline') }}
                      </span>
                    </template>
                  </td>
                </tr>
              </template>
            </template>
          </tbody>
        </table>
      </div>

      <BlocksPagination
        :key="pageNo"
        :current-page="pageNo"
        :page-size="pageSize"
        :page-block="getPageBlock(breakpoints.isMobile ? 'mobile' : 'desktop')"
        :total-count="totalCount"
        :use-min-max="true"
        @update:page="handlePaging"
      />
    </section>
  </div>

  <ClientOnly>
    <Teleport to="body">
      <BlocksModalLayer
        :is-show-dimmed="true"
        :is-outside-close="true"
        modal-name="modal-coupon-character-select"
        :is-open="isSelectCharacterModalOpen"
        area-class="max-w-[480px] p-6 bg-white rounded-[20px]"
        close-class="hidden"
      >
        <div
          class="relative flex flex-col items-center justify-center gap-[24px] w-full"
        >
          <p
            v-dompurify-html="tm('Coupon_Alert_SelectCharacter')"
            class="relative flex items-start justify-center w-full text-center text-[#333333] text-[15px] font-[400] leading-[24px] tracking-[-0.45px]"
          ></p>

          <AtomsSelect
            :options="sortedCharacterList"
            label-name="formatted_nm"
            :placeholder="tm('Coupon_Alert_EnterCharacter')"
            @update:model-value="updateSelectCharacter"
          />

          <div
            class="relative flex items-center justify-center gap-[8px] w-full"
          >
            <AtomsButtonVariant
              variant="outlined"
              class="max-w-[128px]"
              @click="closeSelectCharacterModal"
            >
              {{ tm('Text_Cancel') }}
            </AtomsButtonVariant>
            <AtomsButtonVariant
              :disabled="isSelectCharacter ? false : true"
              class="max-w-[128px]"
              @click="handleCouponRegister"
            >
              {{ tm('Text_Confirm') }}
            </AtomsButtonVariant>
          </div>
        </div>
      </BlocksModalLayer>
    </Teleport>
  </ClientOnly>
</template>

<style scoped>
/* Button Style */
.btn-period {
  @apply border border-solid border-[#D9D9D9] rounded-[0] w-auto h-[40px] px-[16px] font-[700] before:content-none after:content-none
  transition-all duration-300 ease-in-out
  hover:z-[4] hover:!bg-[#FFFFFF] hover:border-[#404040] hover:!text-[#1F1F1F];
}
.btn-period + .btn-period {
  @apply ml-[-1px];
}
.btn-period:first-child {
  @apply rounded-l-[8px];
}
.btn-period:last-child {
  @apply rounded-r-[8px];
}
.btn-period.btn-period-active {
  @apply z-[4] !bg-[#FFFFFF] !border-[#404040] !text-[#1F1F1F];
}

/* Table Style */
table {
  @apply w-full h-auto border-collapse border-spacing-0 table-auto;
}
table th {
  @apply py-[8px] px-[12px] border border-[#D9D9D9] border-t-[0] border-r-[0] bg-[#FAFAFA] text-[#1F1F1F] text-[14px] font-bold leading-[24px] tracking-[-0.42px]
  md:py-[11px] md:px-[20px] md:text-[16px] md:leading-[26px] md:tracking-[-0.48px];
}
table td {
  @apply h-[auto] p-[12px] border border-[#D9D9D9] border-t-[0] border-r-[0] bg-[#FFFFFF] text-center text-[#666666] text-[14px] font-[400] leading-[24px] tracking-[-0.42px]
  md:px-[20px] md:text-[16px] md:leading-[26px] md:tracking-[-0.48px];
}
table td p {
  @apply line-clamp-2 text-center;
}
/* Coupon Item Style */
.coupon-item {
  @apply relative inline-flex items-center justify-center !w-auto !h-auto py-[2px] px-[6px] border-none rounded-full !bg-[#EBEBEB] text-center !text-[#999999] text-[12px] font-[500] leading-[18px] tracking-[-0.24px]
  md:py-[4px] md:px-[8px] md:text-[14px] md:leading-[20px] md:tracking-[-0.42px];
}
.coupon-item.coupon-item-use {
  @apply !bg-[#383838] !text-white;
}
.coupon-item.coupon-item-used {
  @apply !bg-[#E2EAFF] !text-[#3C75FF];
}
.coupon-item.coupon-item-not-used {
  @apply !bg-[#EEF6F1] !text-[#2B9450];
}
</style>
