<script setup>
const loading = ref(true)
const savingProfile = ref(false)
const savingPassword = ref(false)
const deletingAccount = ref(false)
const uploadingAvatar = ref(false)
const removingAvatar = ref(false)
const profileMessage = ref('')
const passwordMessage = ref('')
const deleteMessage = ref('')

const profileForm = reactive({
  email: '',
  username: '',
  avatarUrl: ''
})

const passwordForm = reactive({
  currentPassword: '',
  nextPassword: '',
  nextPasswordConfirm: ''
})

const deleteForm = reactive({
  password: ''
})

/**
 * 설정 화면 초기 데이터를 조회한다.
 * @returns {Promise<void>}
 */
const loadProfile = async () => {
  try {
    const profile = await $fetch('/api/auth/profile')
    profileForm.email = profile.email || ''
    profileForm.username = profile.username || ''
    profileForm.avatarUrl = profile.avatarUrl || ''
  } catch {
    await navigateTo('/signin')
  } finally {
    loading.value = false
  }
}

/**
 * 닉네임 중복 여부를 확인한다.
 * @returns {Promise<boolean>} 사용 가능 여부
 */
const checkUsernameAvailable = async () => {
  const username = profileForm.username.trim()
  if (!username) {
    profileMessage.value = '닉네임을 입력해 주세요.'
    return false
  }

  try {
    const result = await $fetch('/api/auth/check-username', {
      query: {
        username
      }
    })

    if (!result.available) {
      profileMessage.value = '이미 사용 중인 닉네임입니다.'
      return false
    }
  } catch (error) {
    profileMessage.value = error?.data?.message || '닉네임 중복 확인에 실패했습니다.'
    return false
  }

  return true
}

/**
 * 프로필을 저장한다.
 * @returns {Promise<void>}
 */
const saveProfile = async () => {
  profileMessage.value = ''
  const available = await checkUsernameAvailable()
  if (!available) {
    return
  }

  savingProfile.value = true
  try {
    await $fetch('/api/auth/profile', {
      method: 'PUT',
      body: {
        username: profileForm.username.trim(),
        avatarUrl: profileForm.avatarUrl.trim()
      }
    })
    profileMessage.value = '프로필이 저장되었습니다.'
  } catch (error) {
    profileMessage.value = error?.data?.message || '프로필 저장에 실패했습니다.'
  } finally {
    savingProfile.value = false
  }
}

/**
 * 썸네일을 제거한다.
 * @returns {Promise<void>}
 */
const removeAvatar = async () => {
  if (removingAvatar.value) {
    return
  }

  removingAvatar.value = true
  profileMessage.value = ''

  try {
    await $fetch('/api/auth/avatar', {
      method: 'DELETE'
    })
    profileForm.avatarUrl = ''
    profileMessage.value = '썸네일이 제거되었습니다.'
  } catch (error) {
    profileMessage.value = error?.data?.message || '썸네일 제거에 실패했습니다.'
  } finally {
    removingAvatar.value = false
  }
}

/**
 * 썸네일 파일을 업로드한다.
 * @param {Event} event - 파일 선택 이벤트
 * @returns {Promise<void>}
 */
const uploadAvatar = async (event) => {
  const target = /** @type {HTMLInputElement | null} */ (event.target instanceof HTMLInputElement ? event.target : null)
  const file = target?.files?.[0]

  if (!file || uploadingAvatar.value) {
    return
  }

  uploadingAvatar.value = true
  profileMessage.value = ''

  try {
    const formData = new FormData()
    formData.append('file', file)
    const result = await $fetch('/api/auth/avatar', {
      method: 'POST',
      body: formData
    })
    profileForm.avatarUrl = result.avatarUrl || ''
    profileMessage.value = '썸네일이 업로드되었습니다. 프로필 저장을 눌러 반영하세요.'
  } catch (error) {
    profileMessage.value = error?.data?.message || '썸네일 업로드에 실패했습니다.'
  } finally {
    uploadingAvatar.value = false
    if (target) {
      target.value = ''
    }
  }
}

/**
 * 비밀번호를 변경한다.
 * @returns {Promise<void>}
 */
const savePassword = async () => {
  passwordMessage.value = ''
  if (!passwordForm.currentPassword || !passwordForm.nextPassword || !passwordForm.nextPasswordConfirm) {
    passwordMessage.value = '모든 비밀번호 입력값을 작성해 주세요.'
    return
  }
  if (passwordForm.nextPassword !== passwordForm.nextPasswordConfirm) {
    passwordMessage.value = '새 비밀번호와 확인 값이 일치하지 않습니다.'
    return
  }

  savingPassword.value = true
  try {
    await $fetch('/api/auth/password', {
      method: 'PUT',
      body: {
        currentPassword: passwordForm.currentPassword,
        nextPassword: passwordForm.nextPassword
      }
    })
    passwordForm.currentPassword = ''
    passwordForm.nextPassword = ''
    passwordForm.nextPasswordConfirm = ''
    passwordMessage.value = '비밀번호가 변경되었습니다.'
  } catch (error) {
    passwordMessage.value = error?.data?.message || '비밀번호 변경에 실패했습니다.'
  } finally {
    savingPassword.value = false
  }
}

/**
 * 회원 탈퇴를 처리한다.
 * @returns {Promise<void>}
 */
const removeAccount = async () => {
  deleteMessage.value = ''
  if (!deleteForm.password) {
    deleteMessage.value = '탈퇴 확인용 비밀번호를 입력해 주세요.'
    return
  }

  deletingAccount.value = true
  try {
    await $fetch('/api/auth/account', {
      method: 'DELETE',
      body: {
        password: deleteForm.password
      }
    })
    await navigateTo('/')
  } catch (error) {
    deleteMessage.value = error?.data?.message || '회원 탈퇴에 실패했습니다.'
  } finally {
    deletingAccount.value = false
  }
}

onMounted(loadProfile)
</script>

<template>
  <section class="settings-page mx-auto w-full max-w-[720px] px-4 py-8 sm:px-5">
    <h1 class="text-xl font-semibold">사용자 설정</h1>

    <div v-if="loading" class="mt-4 text-sm site-muted">
      설정 정보를 불러오는 중입니다.
    </div>

    <div v-else class="mt-5 flex flex-col gap-5">
      <section class="rounded-[10px] border border-[var(--site-line)] bg-[var(--site-bg)] p-4">
        <h2 class="text-sm font-semibold">프로필</h2>
        <div class="mt-3 flex flex-col gap-3">
          <label class="text-xs site-muted">이메일</label>
          <input
            v-model="profileForm.email"
            type="text"
            disabled
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-[var(--site-panel)] px-3 text-sm"
          >
          <label class="text-xs site-muted">닉네임</label>
          <input
            v-model="profileForm.username"
            type="text"
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
          >
          <label class="text-xs site-muted">썸네일 URL</label>
          <input
            v-model="profileForm.avatarUrl"
            type="text"
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
            placeholder="https://..."
          >
          <button
            type="button"
            class="w-fit rounded-[10px] border border-[var(--site-line)] px-3 py-1.5 text-xs site-muted transition-opacity hover:opacity-80 disabled:opacity-60"
            :disabled="removingAvatar"
            @click="removeAvatar"
          >
            {{ removingAvatar ? '제거 중...' : '썸네일 제거' }}
          </button>
          <label class="text-xs site-muted">썸네일 업로드</label>
          <input
            type="file"
            accept="image/jpeg,image/png,image/webp,image/gif"
            class="block w-full text-xs site-muted file:mr-3 file:cursor-pointer file:rounded-[8px] file:border file:border-[var(--site-line)] file:bg-[var(--site-panel)] file:px-3 file:py-1.5"
            :disabled="uploadingAvatar"
            @change="uploadAvatar"
          >
          <button
            type="button"
            class="site-accent-button mt-1 w-fit rounded-[10px] px-3 py-1.5 text-xs font-semibold disabled:opacity-60"
            :disabled="savingProfile"
            @click="saveProfile"
          >
            {{ savingProfile ? '저장 중...' : '프로필 저장' }}
          </button>
          <p v-if="profileMessage" class="text-xs site-muted">
            {{ profileMessage }}
          </p>
        </div>
      </section>

      <section class="rounded-[10px] border border-[var(--site-line)] bg-[var(--site-bg)] p-4">
        <h2 class="text-sm font-semibold">비밀번호 변경</h2>
        <div class="mt-3 flex flex-col gap-3">
          <input
            v-model="passwordForm.currentPassword"
            type="password"
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
            placeholder="현재 비밀번호"
          >
          <input
            v-model="passwordForm.nextPassword"
            type="password"
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
            placeholder="새 비밀번호"
          >
          <input
            v-model="passwordForm.nextPasswordConfirm"
            type="password"
            class="h-10 rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-[var(--site-accent)]"
            placeholder="새 비밀번호 확인"
          >
          <button
            type="button"
            class="site-accent-button mt-1 w-fit rounded-[10px] px-3 py-1.5 text-xs font-semibold disabled:opacity-60"
            :disabled="savingPassword"
            @click="savePassword"
          >
            {{ savingPassword ? '변경 중...' : '비밀번호 변경' }}
          </button>
          <p v-if="passwordMessage" class="text-xs site-muted">
            {{ passwordMessage }}
          </p>
        </div>
      </section>

      <section class="rounded-[10px] border border-[var(--site-line)] bg-[var(--site-bg)] p-4">
        <h2 class="text-sm font-semibold text-red-500/70">회원 탈퇴</h2>
        <p class="mt-2 text-xs site-muted">
          탈퇴 시 작성한 댓글과 계정 정보가 삭제됩니다.
        </p>
        <input
          v-model="deleteForm.password"
          type="password"
          class="mt-3 h-10 w-full rounded-[8px] border border-[var(--site-line)] bg-transparent px-3 text-sm outline-none focus-visible:border-red-400"
          placeholder="비밀번호 확인"
        >
        <button
          type="button"
          class="mt-3 rounded-[10px] border border-red-400/40 px-3 py-1.5 text-xs text-red-500/70 transition-opacity hover:opacity-80 disabled:opacity-50"
          :disabled="deletingAccount"
          @click="removeAccount"
        >
          {{ deletingAccount ? '처리 중...' : '회원 탈퇴' }}
        </button>
        <p v-if="deleteMessage" class="mt-2 text-xs site-muted">
          {{ deleteMessage }}
        </p>
      </section>
    </div>
  </section>
</template>

