import Taro from '@tarojs/taro'
import { callCloud, canUseCloud } from './cloud'
import { resolveCloudFileUrl } from './cloud-file'
import { mockProfile } from './mock'
import { normalizeUser } from '@/utils/user'
import type { UserProfile } from '@/types/domain'

export interface LoginResult {
  user: UserProfile
  isNew: boolean
}

// openid login is silent, so "logout" is tracked with a local flag that gates
// auto-restore of the authorized profile until the user logs in again.
const LOGGED_OUT_KEY = 'wq:loggedOut'

export function isLoggedOut(): boolean {
  try {
    return Boolean(Taro.getStorageSync(LOGGED_OUT_KEY))
  } catch {
    return false
  }
}

function setLoggedOut(value: boolean) {
  try {
    if (value) Taro.setStorageSync(LOGGED_OUT_KEY, true)
    else Taro.removeStorageSync(LOGGED_OUT_KEY)
  } catch {
    /* storage unavailable — ignore */
  }
}

export async function logout(): Promise<void> {
  setLoggedOut(true)
}

export async function login(): Promise<LoginResult> {
  if (!canUseCloud()) return { user: mockProfile, isNew: false }
  try {
    const result = await callCloud<object, { user: UserProfile; isNew: boolean }>('login', {})
    const user = normalizeUser(result.user)
    return {
      user: { ...user, avatarUrl: await resolveCloudFileUrl(user.avatarUrl) },
      isNew: Boolean(result.isNew)
    }
  } catch {
    return { user: mockProfile, isNew: false }
  }
}

// Upload a WeChat-chosen avatar temp file to cloud storage and return its fileID.
export async function uploadAvatar(avatarTempPath: string): Promise<string> {
  if (!avatarTempPath || !canUseCloud() || !Taro.cloud) return ''
  const ext = avatarTempPath.split('.').pop()?.split('?')[0] || 'png'
  const cloudPath = `avatars/${Date.now()}-${Math.floor(Math.random() * 1e6)}.${ext}`
  const uploaded = await Taro.cloud.uploadFile({ cloudPath, filePath: avatarTempPath })
  return uploaded.fileID
}

// Upload the WeChat-chosen avatar to cloud storage, then save nickname + avatar to the user record.
export async function completeLogin(avatarTempPath: string, nickname: string): Promise<UserProfile> {
  const trimmed = nickname.trim()
  setLoggedOut(false)

  if (!canUseCloud() || !Taro.cloud) {
    return { ...mockProfile, nickname: trimmed, profileCompleted: true }
  }

  const avatarUrl = await uploadAvatar(avatarTempPath)
  const result = await callCloud<object, { user: UserProfile }>('profileUpdate', {
    patch: { nickname: trimmed, avatarUrl }
  })
  const user = normalizeUser(result.user)
  return { ...user, avatarUrl: await resolveCloudFileUrl(user.avatarUrl) }
}
