// Auth service for LNbits integration
import { ref, computed } from 'vue'
import { BaseService } from '@/core/base/BaseService'
import { eventBus } from '@/core/event-bus'
import type { LoginCredentials, RegisterData, User } from '@/lib/api/lnbits'

export class AuthService extends BaseService {
  // Service metadata
  protected readonly metadata = {
    name: 'AuthService',
    version: '1.0.0',
    dependencies: ['LnbitsAPI'] // Auth service depends on LnbitsAPI for authentication
  }

  // Public state
  public isAuthenticated = ref(false)
  public user = ref<User | null>(null)
  public isLoading = ref(false)
  public error = ref<Error | null>(null)
  
  // Computed properties for compatibility with global auth
  public currentUser = computed(() => this.user.value)
  public userDisplay = computed(() => {
    if (!this.user.value) return null
    
    return {
      name: this.user.value.username || this.user.value.email || 'Anonymous',
      username: this.user.value.username,
      email: this.user.value.email,
      id: this.user.value.id,
      shortId: this.user.value.id.slice(0, 8) + '...' + this.user.value.id.slice(-8)
    }
  })

  /**
   * Service-specific initialization (called by BaseService)
   */
  protected async onInitialize(): Promise<void> {
    this.debug('Initializing auth service...')
    
    // Check for existing auth state and fetch user data
    await this.checkAuth()
    
    if (this.isAuthenticated.value) {
      eventBus.emit('auth:login', { user: this.user.value }, 'auth-service')
    }
  }

  async checkAuth(): Promise<boolean> {
    if (!this.lnbitsAPI.isAuthenticated()) {
      this.debug('No auth token found - user needs to login')
      this.isAuthenticated.value = false
      this.user.value = null
      return false
    }

    try {
      this.isLoading.value = true
      const userData = await this.lnbitsAPI.getCurrentUser()
      
      this.user.value = userData
      this.isAuthenticated.value = true
      
      this.debug(`User authenticated: ${userData.username || userData.id} (${userData.pubkey?.slice(0, 8)})`)
      
      return true
      
    } catch (error) {
      this.handleError(error, 'checkAuth')
      this.isAuthenticated.value = false
      this.user.value = null
      // Clear invalid token
      this.lnbitsAPI.logout()
      return false
    } finally {
      this.isLoading.value = false
    }
  }

  async login(credentials: LoginCredentials): Promise<void> {
    this.isLoading.value = true
    
    try {
      await this.lnbitsAPI.login(credentials)
      const userData = await this.lnbitsAPI.getCurrentUser()
      
      this.user.value = userData
      this.isAuthenticated.value = true
      
      eventBus.emit('auth:login', { user: userData }, 'auth-service')
      
    } catch (error) {
      const err = this.handleError(error, 'login')
      eventBus.emit('auth:login-failed', { error: err }, 'auth-service')
      throw err
    } finally {
      this.isLoading.value = false
    }
  }

  async register(data: RegisterData): Promise<void> {
    this.isLoading.value = true
    
    try {
      await this.lnbitsAPI.register(data)
      const userData = await this.lnbitsAPI.getCurrentUser()
      
      this.user.value = userData
      this.isAuthenticated.value = true
      
      eventBus.emit('auth:login', { user: userData }, 'auth-service')
      
    } catch (error) {
      const err = this.handleError(error, 'register')
      eventBus.emit('auth:login-failed', { error: err }, 'auth-service')
      throw err
    } finally {
      this.isLoading.value = false
    }
  }

  async logout(): Promise<void> {
    this.lnbitsAPI.logout()
    this.user.value = null
    this.isAuthenticated.value = false
    this.error.value = null
    
    eventBus.emit('auth:logout', {}, 'auth-service')
  }

  async refresh(): Promise<void> {
    // Re-fetch user data from API
    await this.checkAuth()
  }

  
  async initialize(): Promise<void> {
    // Call BaseService initialize first to inject dependencies
    await super.initialize()
  }
  
  async updatePassword(currentPassword: string, newPassword: string): Promise<void> {
    try {
      this.isLoading.value = true
      const updatedUser = await this.lnbitsAPI.updatePassword(currentPassword, newPassword)
      this.user.value = updatedUser
    } catch (error) {
      const err = this.handleError(error, 'updatePassword')
      throw err
    } finally {
      this.isLoading.value = false
    }
  }
  
  async updateProfile(data: Partial<User>): Promise<void> {
    try {
      this.isLoading.value = true
      const updatedUser = await this.lnbitsAPI.updateProfile(data)
      this.user.value = updatedUser
    } catch (error) {
      const err = this.handleError(error, 'updateProfile')
      throw err
    } finally {
      this.isLoading.value = false
    }
  }

  /**
   * Cleanup when service is disposed
   */
  protected async onDispose(): Promise<void> {
    this.logout()
    this.debug('Auth service disposed')
  }
}

// Export singleton instance
export const auth = new AuthService()