<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { Badge } from '@/components/ui/badge'
import { Box } from '@/components/ui/box'
import { Button } from '@/components/ui/button'
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
  getPhoneVerificationErrorMessage,
  sendAuthenticatedPhoneVerificationOtp,
  verifyAuthenticatedPhoneVerificationOtp,
} from '@/modules/auth'
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()

const loading = ref(false)
const changingPhone = ref(false)
const otpSent = ref(false)
const phoneNumber = ref(authStore.user?.phone_number ?? '')
const otp = ref('')
const feedbackMessage = ref('')
const errorMessage = ref('')

const isVerified = computed(() => authStore.isPhoneVerified)

const sectionDescription = computed(() => {
  if (changingPhone.value) {
    return 'Masukkan nombor telefon baharu dan sahkan dengan kod OTP SMS.'
  }

  if (isVerified.value) {
    return 'Nombor telefon anda telah disahkan.'
  }

  return 'Sahkan nombor telefon anda melalui kod OTP SMS.'
})

watch(
  () => authStore.user?.phone_number,
  (value) => {
    if (!otpSent.value && !changingPhone.value) {
      phoneNumber.value = value ?? ''
    }
  },
)

const resetOtpState = () => {
  otp.value = ''
  otpSent.value = false
  clearMessages()
}

const clearMessages = () => {
  feedbackMessage.value = ''
  errorMessage.value = ''
}

const handlePhoneInput = () => {
  phoneNumber.value = phoneNumber.value.replace(/[^\d+]/g, '')
  otp.value = ''
  otpSent.value = false
}

const handleOtpInput = () => {
  otp.value = otp.value.replace(/\D/g, '').slice(0, 6)
}

const startChangePhone = () => {
  changingPhone.value = true
  phoneNumber.value = ''
  resetOtpState()
}

const cancelChangePhone = () => {
  changingPhone.value = false
  phoneNumber.value = authStore.user?.phone_number ?? ''
  resetOtpState()
}

const handleSendOtp = async () => {
  loading.value = true
  clearMessages()

  try {
    const response = await sendAuthenticatedPhoneVerificationOtp({
      phone_number: phoneNumber.value,
    })

    feedbackMessage.value = response.message
    otpSent.value = true
  } catch (error) {
    errorMessage.value = getPhoneVerificationErrorMessage(error)
  } finally {
    loading.value = false
  }
}

const handleVerifyOtp = async () => {
  loading.value = true
  clearMessages()

  try {
    const response = await verifyAuthenticatedPhoneVerificationOtp({
      phone_number: phoneNumber.value,
      otp: otp.value,
    })

    authStore.setUserProfile(response.data)
    phoneNumber.value = response.data.phone_number ?? phoneNumber.value
    changingPhone.value = false
    otp.value = ''
    otpSent.value = false
    feedbackMessage.value = response.message
  } catch (error) {
    errorMessage.value = getPhoneVerificationErrorMessage(error)
  } finally {
    loading.value = false
  }
}
</script>

<template>
  <Box raised="single" class="p-6">
    <div class="mb-6">
      <h3 class="text-lg font-semibold text-slate-900">Nombor Telefon</h3>
      <p class="mt-1 text-sm text-slate-500">
        {{ sectionDescription }}
      </p>
    </div>

    <div v-if="isVerified && !changingPhone" class="space-y-4">
      <div class="flex flex-wrap items-center gap-3">
        <Input id="profile-phone-verified" :model-value="authStore.user?.phone_number ?? '-'" type="tel" disabled
          class="max-w-sm" />
        <Badge variant="success">Disahkan</Badge>
      </div>

      <p v-if="feedbackMessage" class="text-sm text-slate-600">{{ feedbackMessage }}</p>

      <Button type="button" look="outline" :disabled="loading" @click="startChangePhone">
        Tukar Nombor Telefon
      </Button>
    </div>

    <div v-else class="space-y-4">
      <FieldGroup>
        <Field class="max-w-sm">
          <FieldLabel for="profile-phone-verify">No. Telefon</FieldLabel>
          <Input id="profile-phone-verify" v-model="phoneNumber" type="tel" inputmode="tel"
            placeholder="No. Telefon, contoh: 0123456790" autocomplete="tel" :disabled="loading || otpSent"
            @input="handlePhoneInput" />
        </Field>
        <Field v-if="otpSent" class="max-w-sm">
          <FieldLabel for="profile-phone-otp">Kod OTP</FieldLabel>
          <Input id="profile-phone-otp" v-model="otp" type="text" inputmode="numeric" maxlength="6" placeholder="000000"
            autocomplete="one-time-code" class="text-center tracking-[0.4em]" :disabled="loading"
            @input="handleOtpInput" />
        </Field>
      </FieldGroup>

      <p v-if="feedbackMessage" class="text-sm text-slate-600">{{ feedbackMessage }}</p>
      <p v-if="errorMessage" class="text-sm text-danger">{{ errorMessage }}</p>

      <div class="flex flex-wrap gap-2">
        <Button v-if="!otpSent" type="button" variant="primary" :disabled="loading || !phoneNumber"
          @click="handleSendOtp">
          {{ loading ? 'Menghantar...' : 'Hantar Kod OTP' }}
        </Button>
        <template v-else>
          <Button type="button" variant="primary" :disabled="loading || otp.length !== 6" @click="handleVerifyOtp">
            {{ loading ? 'Mengesahkan...' : 'Sahkan OTP' }}
          </Button>
          <Button type="button" look="outline" :disabled="loading" @click="handleSendOtp">
            Hantar Semula OTP
          </Button>
        </template>
        <Button v-if="changingPhone" type="button" look="outline" :disabled="loading" @click="cancelChangePhone">
          Batal
        </Button>
      </div>
    </div>
  </Box>
</template>
