import { Client, Account, Databases, ID } from 'appwrite'

const client = new Client()

// Configure these in your .env file
const APPWRITE_ENDPOINT = import.meta.env.VITE_APPWRITE_ENDPOINT || 'https://cloud.appwrite.io/v1'
const APPWRITE_PROJECT_ID = (import.meta.env.VITE_APPWRITE_PROJECT_ID || '').trim()

/** Ohne Project ID keine gültigen Appwrite-Requests — sonst nur 401-Spam im Netzwerk-Tab. */
export function isAppwriteClientConfigured(): boolean {
  return APPWRITE_PROJECT_ID.length > 0
}

function assertAppwriteConfigured(): void {
  if (!isAppwriteClientConfigured()) {
    throw new Error(
      'Appwrite ist nicht konfiguriert: Lege client/.env an und setze VITE_APPWRITE_PROJECT_ID (siehe client/.env.example). Danach Vite neu starten.'
    )
  }
}

client
  .setEndpoint(APPWRITE_ENDPOINT)
  .setProject(APPWRITE_PROJECT_ID)

if (import.meta.env.DEV && !isAppwriteClientConfigured()) {
  console.warn(
    '[MailFlow] VITE_APPWRITE_PROJECT_ID fehlt → keine Appwrite-Aufrufe bis client/.env gesetzt ist. Kopiere client/.env.example nach client/.env.'
  )
}

/** Vite-Dev mit Proxy: Endpoint zeigt auf localhost → Session liegt in cookieFallback (localStorage). */
function isLocalViteAppwriteProxy(): boolean {
  if (typeof window === 'undefined') return false
  return /localhost|127\.0\.0\.1/.test(APPWRITE_ENDPOINT)
}

function hasCookieFallbackSession(): boolean {
  if (typeof window === 'undefined' || !APPWRITE_PROJECT_ID) return false
  try {
    const raw = window.localStorage.getItem('cookieFallback')
    if (!raw) return false
    const o = JSON.parse(raw) as Record<string, unknown>
    return Boolean(o[`a_session_${APPWRITE_PROJECT_ID}`])
  } catch {
    return false
  }
}

export const account = new Account(client)
export const databases = new Databases(client)
export { ID }

const JWT_BUFFER_MS = 30_000
let jwtCache: { token: string; expMs: number } | null = null

export function clearApiJwtCache() {
  jwtCache = null
}

/** Short-lived JWT for MailFlow API (Bearer). Cached until near expiry. */
export async function getApiJwt(): Promise<string | null> {
  if (!isAppwriteClientConfigured()) {
    return null
  }
  if (isLocalViteAppwriteProxy() && !hasCookieFallbackSession()) {
    return null
  }
  try {
    const now = Date.now()
    if (jwtCache && jwtCache.expMs > now + JWT_BUFFER_MS) {
      return jwtCache.token
    }
    const res = await account.createJWT()
    const token = res.jwt
    const expireSec = (res as { expire?: number }).expire
    const expMs = expireSec != null ? expireSec * 1000 : now + 14 * 60 * 1000
    jwtCache = { token, expMs }
    return token
  } catch {
    return null
  }
}

// Auth helper functions
export const auth = {
  // Create a new account
  async register(email: string, password: string, name?: string) {
    assertAppwriteConfigured()
    const user = await account.create(ID.unique(), email, password, name)
    await this.login(email, password)
    return user
  },

  // Login with email and password
  async login(email: string, password: string) {
    assertAppwriteConfigured()
    return await account.createEmailPasswordSession(email, password)
  },

  // Logout current session
  async logout() {
    clearApiJwtCache()
    if (!isAppwriteClientConfigured()) {
      return
    }
    return await account.deleteSession('current')
  },

  // Get current logged in user
  async getCurrentUser() {
    if (!isAppwriteClientConfigured()) {
      return null
    }
    if (isLocalViteAppwriteProxy() && !hasCookieFallbackSession()) {
      return null
    }
    try {
      return await account.get()
    } catch {
      return null
    }
  },

  // Check if user is logged in
  async isLoggedIn() {
    if (!isAppwriteClientConfigured()) {
      return false
    }
    if (isLocalViteAppwriteProxy() && !hasCookieFallbackSession()) {
      return false
    }
    try {
      await account.get()
      return true
    } catch {
      return false
    }
  },

  // Send password recovery email
  async forgotPassword(email: string) {
    assertAppwriteConfigured()
    return await account.createRecovery(
      email,
      `${window.location.origin}/reset-password`
    )
  },

  // Complete password recovery
  async resetPassword(userId: string, secret: string, newPassword: string) {
    assertAppwriteConfigured()
    return await account.updateRecovery(userId, secret, newPassword)
  },

  // Send verification email
  async sendVerification() {
    assertAppwriteConfigured()
    return await account.createVerification(
      `${window.location.origin}/verify`
    )
  },

  // Complete email verification
  async verifyEmail(userId: string, secret: string) {
    assertAppwriteConfigured()
    return await account.updateVerification(userId, secret)
  },
}

export default client
