import { defineStore } from 'pinia'
import { ref, computed, readonly } from 'vue'

type SubscriptionStatus = {
  status?: string
  endDate?: string | null
  isActive?: boolean
  isAdmin?: boolean
} | null

export const useAuthStore = defineStore('auth', () => {
  const user = ref<Record<string, any> | null>(null)
  const token = ref<string | null>(null)
  const subscriptionStatus = ref<SubscriptionStatus>(null)
  const initialized = ref(false)
  let initializationPromise: Promise<void> | null = null
  let subscriptionPromise: Promise<any> | null = null
  const SUBSCRIPTION_STORAGE_KEY = 'subscription_status_cache'
  const SUBSCRIPTION_CACHE_TTL = 5 * 60 * 1000
  const memoryStorage = new Map<string, string>()

  const getStorage = () => {
    if (!process.client) return null

    try {
      if (typeof window !== 'undefined' && window.localStorage) {
        return window.localStorage
      }
    } catch {
      // Fall back to in-memory storage for restricted webviews.
    }

    return {
      getItem(key: string) {
        return memoryStorage.has(key) ? memoryStorage.get(key)! : null
      },
      setItem(key: string, value: string) {
        memoryStorage.set(key, String(value))
      },
      removeItem(key: string) {
        memoryStorage.delete(key)
      }
    }
  }

  const getStorageKeys = () => {
    if (!process.client) return []

    try {
      if (typeof window !== 'undefined' && window.localStorage) {
        return Object.keys(window.localStorage)
      }
    } catch {
      // Fall back to in-memory storage for restricted webviews.
    }

    return Array.from(memoryStorage.keys())
  }

  const isAuthenticated = computed(() => !!user.value)
  const isLoggedIn = computed(() => !!user.value)
  const hasActiveSubscription = computed(() => {
    // 관리자 계정은 항상 활성 상태
    if (subscriptionStatus.value?.isAdmin) {
      return true
    }
    return subscriptionStatus.value?.isActive || false
  })

  const clearDraftStorage = () => {
    const storage = getStorage()
    if (!storage) return

    getStorageKeys().forEach((key) => {
      if (key.startsWith('recovery_page')) {
        storage.removeItem(key)
      }
    })

    storage.removeItem('recovery_current_case_id')
  }

  const loadCachedSubscriptionStatus = () => {
    const storage = getStorage()
    if (!storage) return null

    try {
      const raw = storage.getItem(SUBSCRIPTION_STORAGE_KEY)
      if (!raw) return null

      const parsed = JSON.parse(raw)
      if (!parsed?.value || !parsed?.cachedAt) return null

      if (Date.now() - Number(parsed.cachedAt) > SUBSCRIPTION_CACHE_TTL) {
        storage.removeItem(SUBSCRIPTION_STORAGE_KEY)
        return null
      }

      return parsed.value
    } catch {
      storage.removeItem(SUBSCRIPTION_STORAGE_KEY)
      return null
    }
  }

  const persistSubscriptionStatus = (value) => {
    const storage = getStorage()
    if (!storage) return

    storage.setItem(SUBSCRIPTION_STORAGE_KEY, JSON.stringify({
      value,
      cachedAt: Date.now()
    }))
  }

  // 로그인
  const login = async (credentials) => {
    try {
      const data = await $fetch('/auth/login', {
        method: 'POST',
        body: credentials,
        baseURL: useRuntimeConfig().public.apiBase
      })

      if (data.success) {
        user.value = data.user
        token.value = data.token

        // localStorage에 토큰 저장
        const storage = getStorage()
        if (storage && data.token) {
          storage.setItem('token', data.token)
        }

        initialized.value = true
        await loadSubscriptionStatus()
        return { success: true, message: data.message }
      } else {
        throw new Error(data.message || '로그인에 실패했습니다.')
      }
    } catch (error) {
      console.error('Login error:', error)
      const message = error.data?.message || error.message || '로그인에 실패했습니다.'
      throw new Error(message)
    }
  }

  // 회원가입
  const register = async (userData) => {
    try {
      const data = await $fetch('/auth/register', {
        method: 'POST',
        body: userData,
        baseURL: useRuntimeConfig().public.apiBase
      })

      if (data.success) {
        return { success: true, message: data.message }
      } else {
        throw new Error(data.message || '회원가입에 실패했습니다.')
      }
    } catch (error) {
      console.error('Registration error:', error)
      const message = error.data?.message || error.message || '회원가입에 실패했습니다.'
      throw new Error(message)
    }
  }

  // 로그아웃
  const logout = async () => {
    user.value = null
    token.value = null
    subscriptionStatus.value = null

    const storage = getStorage()
    if (storage) {
      storage.removeItem('token')
      storage.removeItem(SUBSCRIPTION_STORAGE_KEY)
      clearDraftStorage()
    }

    await navigateTo('/')
  }

  // 사용자 정보 가져오기
  const loadUser = async () => {
    if (!token.value) return false

    try {
      const data = await $fetch('/auth/me', {
        baseURL: useRuntimeConfig().public.apiBase,
        headers: {
          Authorization: `Bearer ${token.value}`
        }
      })

      if (data.success && data.user) {
        user.value = data.user
        return true
      }
    } catch (error) {
      console.error('Fetch user error:', error)
      user.value = null
      token.value = null

      const storage = getStorage()
      if (storage) {
        storage.removeItem('token')
      }
    }
    return false
  }

  // 구독 상태 가져오기
  const loadSubscriptionStatus = async () => {
    if (!token.value) return null

    if (subscriptionStatus.value?.isAdmin) {
      return subscriptionStatus.value
    }

    if (subscriptionStatus.value) {
      return subscriptionStatus.value
    }

    const cached = loadCachedSubscriptionStatus()
    if (cached) {
      subscriptionStatus.value = cached
      return cached
    }

    if (subscriptionPromise) {
      return subscriptionPromise
    }

    subscriptionPromise = (async () => {
      try {
      const data = await $fetch('/payment/subscription-status', {
        baseURL: useRuntimeConfig().public.apiBase,
        headers: {
          Authorization: `Bearer ${token.value}`
        }
      })

      subscriptionStatus.value = data
      persistSubscriptionStatus(data)
      return data
    } catch (error) {
      console.error('Failed to load subscription status:', error)
      return null
    } finally {
      subscriptionPromise = null
    }
    })()

    return subscriptionPromise
  }

  // 초기화
  const initializeAuth = async () => {
    if (!process.client) return

    if (initialized.value) return

    if (initializationPromise) {
      return initializationPromise
    }

    initializationPromise = (async () => {
      try {
        const storage = getStorage()
        const storedToken = storage?.getItem('token')
        if (storedToken) {
          token.value = storedToken
          const cachedSubscriptionStatus = loadCachedSubscriptionStatus()
          if (cachedSubscriptionStatus) {
            subscriptionStatus.value = cachedSubscriptionStatus
          }
          await loadUser()

          // 구독 상태는 라우트 진입을 막지 않도록 백그라운드에서 갱신
          if (user.value && !subscriptionStatus.value) {
            loadSubscriptionStatus().catch((error) => {
              console.error('Background subscription load failed:', error)
            })
          }
        }
      } catch (error) {
        console.error('Auth initialization error:', error)
        // 오류 발생 시 토큰 정리
        token.value = null
        user.value = null
        subscriptionStatus.value = null
        const storage = getStorage()
        storage?.removeItem('token')
        storage?.removeItem(SUBSCRIPTION_STORAGE_KEY)
      } finally {
        initialized.value = true
        initializationPromise = null
      }
    })()

    return initializationPromise
  }

  return {
    user: readonly(user),
    token: readonly(token),
    subscriptionStatus: readonly(subscriptionStatus),
    initialized: readonly(initialized),
    isAuthenticated,
    isLoggedIn,
    hasActiveSubscription,
    login,
    register,
    logout,
    loadUser,
    loadSubscriptionStatus,
    initializeAuth
  }
})
