interface LoginCredentials {
  username: string
  password: string
}

interface RegisterData {
  username: string
  email?: string
  password: string
  password_repeat: string
}

interface AuthResponse {
  access_token: string
  user_id: string
  username?: string
  email?: string
}

interface Wallet {
  id: string
  user: string
  name: string
  adminkey: string
  inkey: string
  deleted: boolean
  created_at: string
  updated_at: string
  currency?: string
  balance_msat: number
  extra?: {
    icon: string
    color: string
    pinned: boolean
  }
}

interface User {
  id: string
  username?: string
  email?: string
  pubkey?: string
  prvkey?: string  // Nostr private key for user
  external_id?: string
  extensions: string[]
  wallets: Wallet[]
  admin: boolean
  super_user: boolean
  fiat_providers: string[]
  has_password: boolean
  created_at: string
  updated_at: string
  extra?: {
    email_verified?: boolean
    first_name?: string
    last_name?: string
    display_name?: string
    picture?: string
    provider?: string
    visible_wallet_count?: number
  }
}

import { BaseService } from '@/core/base/BaseService'
import { getApiUrl, getAuthToken, setAuthToken, removeAuthToken } from '@/lib/config/lnbits'

export class LnbitsAPI extends BaseService {
  // Service metadata
  protected readonly metadata = {
    name: 'LnbitsAPI',
    version: '1.0.0',
    dependencies: [] // No dependencies - this is a core infrastructure service
  }

  private accessToken: string | null = null

  constructor() {
    super()
    // Try to load token from localStorage
    this.accessToken = getAuthToken()
  }

  /**
   * Service-specific initialization (called by BaseService)
   */
  protected async onInitialize(): Promise<void> {
    this.debug('LnbitsAPI initialized')
    // Service is ready to use
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = getApiUrl(endpoint)
    console.log('🔧 LNBits API request:', { endpoint, fullUrl: url })
    
    const headers: HeadersInit = {
      'Content-Type': 'application/json',
      ...options.headers,
    }

    if (this.accessToken) {
      (headers as Record<string, string>)['Authorization'] = `Bearer ${this.accessToken}`
    }

    const response = await fetch(url, {
      ...options,
      headers,
    })

    if (!response.ok) {
      const errorText = await response.text()
      console.error('LNBits API Error:', {
        status: response.status,
        statusText: response.statusText,
        errorText
      })
      throw new Error(`API request failed: ${response.status} ${response.statusText}`)
    }

    const data = await response.json()
    return data
  }

  async login(credentials: LoginCredentials): Promise<AuthResponse> {
    const response = await this.request<AuthResponse>('/auth', {
      method: 'POST',
      body: JSON.stringify(credentials),
    })

    this.accessToken = response.access_token
    setAuthToken(response.access_token)
    
    return response
  }

  async register(data: RegisterData): Promise<AuthResponse> {
    const response = await this.request<AuthResponse>('/auth/register', {
      method: 'POST',
      body: JSON.stringify(data),
    })

    this.accessToken = response.access_token
    setAuthToken(response.access_token)
    
    return response
  }

  async logout(): Promise<void> {
    // Just clear local state - no API call needed for logout
    this.accessToken = null
    removeAuthToken()
  }

  async getCurrentUser(): Promise<User> {
    // First get basic user info from /auth
    const basicUser = await this.request<User>('/auth')
    
    // Then get Nostr keys from /auth/nostr/me (this was working in main branch)
    try {
      const nostrUser = await this.request<User>('/auth/nostr/me')
      
      // Merge the data - basic user info + Nostr keys
      return {
        ...basicUser,
        pubkey: nostrUser.pubkey,
        prvkey: nostrUser.prvkey
      }
    } catch (error) {
      console.warn('Failed to fetch Nostr keys, returning basic user info:', error)
      // Return basic user info without Nostr keys if the endpoint fails
      return basicUser
    }
  }

  async updatePassword(currentPassword: string, newPassword: string): Promise<User> {
    return this.request<User>('/auth/password', {
      method: 'PUT',
      body: JSON.stringify({
        current_password: currentPassword,
        new_password: newPassword,
      }),
    })
  }

  async updateProfile(data: Partial<User>): Promise<User> {
    return this.request<User>('/auth/update', {
      method: 'PUT',
      body: JSON.stringify(data),
    })
  }

  isAuthenticated(): boolean {
    return !!this.accessToken
  }

  getAccessToken(): string | null {
    return this.accessToken
  }
}

// Service is now registered in the DI container
export type { LoginCredentials, RegisterData, AuthResponse, User } 