<script setup>
import { reactive, ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { useUiStore } from '@/stores/ui'
import { authApi } from '@/api/authApi'
import { isNativeGoogle, nativeGoogleIdToken } from '@/native/googleAuth'
import { isNativeApple, nativeAppleCredential } from '@/native/appleAuth'
import { ID_LOGIN_ENABLED } from '@/config/features'

const auth = useAuthStore()
const ui = useUiStore()
const router = useRouter()

// 로그인 닫고 회원가입 팝업 열기
function goSignup() {
  ui.openSignup()
}

// 소셜 로그인(네이버)은 준비 중 — 잠시 숨김. 구현 완료 시 true 로 전환.
const SOCIAL_LOGIN_ENABLED = false

const form = reactive({ loginId: '', password: '', rememberMe: true })
const loading = ref(false)
const error = ref(null)

// ===== 구글 로그인 =====
// 웹/Electron: GIS(웹) 렌더 버튼.  앱(안드로이드): 네이티브 Credential Manager 버튼.
const isNative = isNativeGoogle()
const GIS_SRC = 'https://accounts.google.com/gsi/client'
const googleClientId = ref('')        // 백엔드에서 받은 OAuth 웹 클라이언트 ID (없으면 버튼 숨김)
const googleBtn = ref(null)           // 구글 버튼이 그려질 컨테이너(웹 GIS)
let gisScriptPromise = null           // GIS 스크립트는 한 번만 로드

// ID 토큰으로 세션 발급 → 닫기/이동 (웹·네이티브 공통)
async function finishGoogleLogin(idToken) {
  if (!idToken) return
  error.value = null
  loading.value = true
  try {
    await auth.googleLogin(idToken, form.rememberMe)
    const redirect = ui.redirectPath
    ui.closeLogin()
    router.push(redirect || '/')
  } catch (e) {
    error.value = e.response?.data?.message || '구글 로그인에 실패했습니다.'
  } finally {
    loading.value = false
  }
}

// 앱(안드로이드) 네이티브 구글 로그인 버튼 클릭
async function handleNativeGoogle() {
  if (loading.value || !googleClientId.value) return
  loading.value = true
  try {
    const idToken = await nativeGoogleIdToken(googleClientId.value)
    loading.value = false
    await finishGoogleLogin(idToken)
  } catch (e) {
    loading.value = false
    // 사용자가 취소한 경우(메시지 없음)는 조용히 무시
    const msg = e?.message || ''
    if (msg && !/cancel/i.test(msg)) error.value = '구글 로그인에 실패했습니다.'
  }
}

// ===== 애플 로그인 (iOS 전용) =====
const isApple = isNativeApple()

async function handleNativeApple() {
  if (loading.value) return
  loading.value = true
  try {
    const { identityToken, name } = await nativeAppleCredential()
    loading.value = false
    if (!identityToken) return
    error.value = null
    loading.value = true
    await auth.appleLogin(identityToken, name, form.rememberMe)
    const redirect = ui.redirectPath
    ui.closeLogin()
    router.push(redirect || '/')
  } catch (e) {
    // 사용자가 취소(USER_CANCELLED/1001 등)한 경우는 조용히 무시
    const msg = `${e?.code || ''} ${e?.message || ''}`
    if (!/cancel|1001/i.test(msg)) {
      error.value = e.response?.data?.message || '애플 로그인에 실패했습니다.'
    }
  } finally {
    loading.value = false
  }
}

// GIS 스크립트 로드 (한 번만). 실패하면 reject.
function loadGisScript() {
  if (window.google?.accounts?.id) return Promise.resolve()
  if (gisScriptPromise) return gisScriptPromise
  gisScriptPromise = new Promise((resolve, reject) => {
    const s = document.createElement('script')
    s.src = GIS_SRC
    s.async = true
    s.defer = true
    s.onload = () => resolve()
    s.onerror = () => {
      gisScriptPromise = null
      reject(new Error('GIS load failed'))
    }
    document.head.appendChild(s)
  })
  return gisScriptPromise
}

// 웹 GIS 자격증명(ID 토큰) 수신 → 공통 처리
function onGoogleCredential(response) {
  finishGoogleLogin(response?.credential)
}

// 모달 열릴 때 구글 버튼 준비. 클라이언트 ID 미설정/스크립트 실패 시 조용히 숨김.
async function setupGoogle() {
  try {
    if (!googleClientId.value) {
      const { clientId } = await authApi.googleClientId()
      googleClientId.value = clientId || ''
    }
    if (!googleClientId.value) return // 서버에 미설정 → 구글 버튼 미노출
    if (isNative) return // 앱: 네이티브 버튼(템플릿)으로 처리 — GIS 스크립트 불필요
    await loadGisScript()
    await nextTick()
    if (!ui.loginOpen || !googleBtn.value) return
    window.google.accounts.id.initialize({
      client_id: googleClientId.value,
      callback: onGoogleCredential,
    })
    googleBtn.value.innerHTML = ''
    window.google.accounts.id.renderButton(googleBtn.value, {
      type: 'standard',
      theme: 'outline',
      size: 'large',
      shape: 'rectangular',
      text: 'continue_with',
      logo_alignment: 'center',
      width: 300,
    })
  } catch {
    // 구글 로그인 준비 실패 — 일반 로그인은 그대로 사용 가능하므로 버튼만 숨김
    googleClientId.value = ''
  }
}

// 팝업이 열릴 때마다 입력값 초기화 (로그인 상태 유지는 기본 켜둠)
watch(
  () => ui.loginOpen,
  (open) => {
    if (open) {
      form.loginId = ''
      form.password = ''
      form.rememberMe = true
      error.value = null
      setupGoogle()
    }
  },
)

async function handleLogin() {
  error.value = null
  if (!form.loginId || !form.password) {
    error.value = '아이디와 비밀번호를 입력하세요.'
    return
  }
  loading.value = true
  try {
    await auth.login(form.loginId, form.password, form.rememberMe)
    const redirect = ui.redirectPath
    ui.closeLogin()
    // 가드가 보존한 목적지가 있으면 그곳으로, 없으면 대시보드(홈)로 이동
    router.push(redirect || '/')
  } catch (e) {
    error.value = e.response?.data?.message || '로그인에 실패했습니다.'
  } finally {
    loading.value = false
  }
}

function handleNaverLogin() {
  alert('네이버 로그인은 준비 중입니다.')
}

// ESC 로 닫기
function onKeydown(e) {
  if (e.key === 'Escape' && ui.loginOpen) ui.closeLogin()
}
onMounted(() => window.addEventListener('keydown', onKeydown))
onUnmounted(() => window.removeEventListener('keydown', onKeydown))
</script>

<template>
  <Teleport to="body">
    <Transition name="fade">
      <div v-if="ui.loginOpen" class="modal-backdrop" @click.self="ui.closeLogin()">
        <div class="modal" role="dialog" aria-modal="true" aria-label="로그인">
          <button class="close" type="button" aria-label="닫기" @click="ui.closeLogin()">×</button>
          <h2>로그인</h2>

          <form v-if="ID_LOGIN_ENABLED" class="form" @submit.prevent="handleLogin">
            <input v-model="form.loginId" type="text" placeholder="아이디" autocomplete="username" :disabled="loading" />
            <input v-model="form.password" type="password" placeholder="비밀번호" autocomplete="current-password" :disabled="loading" />
            <label class="remember">
              <input v-model="form.rememberMe" type="checkbox" :disabled="loading" />
              로그인 상태 유지
            </label>
            <button class="submit" type="submit" :disabled="loading">{{ loading ? '로그인 중...' : '로그인' }}</button>
          </form>

          <p v-if="error" class="msg error">{{ error }}</p>

          <!-- 구글 로그인 — 서버에 클라이언트 ID 가 설정된 경우에만 노출 -->
          <div v-show="googleClientId" class="google-wrap">
            <div v-if="ID_LOGIN_ENABLED" class="divider"><span>또는</span></div>
            <!-- 앱(안드로이드): 네이티브 버튼 / 웹·PC: GIS 렌더 버튼 -->
            <button
              v-if="isNative"
              type="button"
              class="google-native"
              :disabled="loading"
              @click="handleNativeGoogle"
            >
              <svg class="g-logo" viewBox="0 0 18 18" width="18" height="18" aria-hidden="true">
                <path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.71-1.57 2.68-3.89 2.68-6.62z"/>
                <path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/>
                <path fill="#FBBC05" d="M3.97 10.72a5.41 5.41 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z"/>
                <path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/>
              </svg>
              Google 계정으로 계속하기
            </button>
            <div v-else ref="googleBtn" class="google-btn"></div>
          </div>

          <!-- 애플 로그인 — iOS 전용(App Store 가이드라인 4.8 대응). 서버 설정 불필요 -->
          <button
            v-if="isApple"
            type="button"
            class="apple-native"
            :disabled="loading"
            @click="handleNativeApple"
          >
            <svg class="a-logo" viewBox="0 0 384 512" width="16" height="16" aria-hidden="true">
              <path fill="currentColor" d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/>
            </svg>
            Apple로 계속하기
          </button>

          <button v-if="SOCIAL_LOGIN_ENABLED" type="button" class="naver" :disabled="loading" @click="handleNaverLogin">
            네이버로 로그인 (준비 중)
          </button>

          <p v-if="ID_LOGIN_ENABLED" class="links">
            <template v-if="ui.signupEnabled">
              계정이 없으신가요?
              <a href="#" @click.prevent="goSignup">회원가입</a>
            </template>
            <span v-else class="signup-off">회원가입이 제한되어 있습니다.</span>
          </p>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  padding: 1rem;
}
.modal {
  position: relative;
  width: 100%;
  max-width: 360px;
  padding: 1.75rem 1.5rem 1.5rem;
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
.close {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  width: 2rem;
  height: 2rem;
  border: 0;
  background: transparent;
  color: var(--color-text);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
h2 {
  margin-bottom: 1.25rem;
  font-size: 1.3rem;
  text-align: center;
}
.form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.form input {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-background-soft);
  color: var(--color-text);
}
.remember {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  cursor: pointer;
}
.remember input {
  width: auto;
  padding: 0;
  cursor: pointer;
}
.submit,
.naver {
  padding: 0.6rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-background-soft);
  color: var(--color-text);
  cursor: pointer;
}
.submit:disabled,
.naver:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.naver {
  width: 100%;
  margin-top: 0.75rem;
  border-color: #03c75a;
  color: #03c75a;
}
.google-wrap {
  margin-top: 1rem;
}
.google-btn {
  display: flex;
  justify-content: center;
}
.google-native {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  max-width: 300px;
  margin: 0 auto;
  padding: 0.6rem 1rem;
  border: 1px solid #747775;
  border-radius: 4px;
  background: #fff;
  color: #1f1f1f;
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
}
.google-native:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.google-native .g-logo {
  flex: none;
}
/* Apple 로그인 버튼 — HIG 권장(검은 배경 + 흰 로고/텍스트) */
.apple-native {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  max-width: 300px;
  margin: 0.6rem auto 0;
  padding: 0.6rem 1rem;
  border: 1px solid #000;
  border-radius: 4px;
  background: #000;
  color: #fff;
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
}
.apple-native:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.apple-native .a-logo {
  flex: none;
  margin-top: -2px;
}
.divider {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.75rem 0;
  color: var(--color-text);
  opacity: 0.55;
  font-size: 0.8rem;
}
.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--color-border);
}
.links {
  margin-top: 1.25rem;
  text-align: center;
  font-size: 0.9rem;
}
.msg {
  margin: 0.75rem 0 0;
}
.msg.error {
  color: #c0392b;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.18s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
