// Events API service for the events module
import type { Event, Ticket, CreateEventRequest } from '../types/event'

export interface EventsApiConfig {
  baseUrl: string
  apiKey: string
}

export class EventsApiService {
  constructor(private config: EventsApiConfig) {}

  async fetchEvents(): Promise<Event[]> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/events/api/v1/events/public`,
        {
          headers: {
            'accept': 'application/json',
          },
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to fetch events'
        throw new Error(errorMessage)
      }

      return await response.json() as Event[]
    } catch (error) {
      console.error('Error fetching events:', error)
      throw error
    }
  }

  async purchaseTicket(eventId: string, userId: string, accessToken: string): Promise<{ payment_hash: string; payment_request: string }> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/events/api/v1/tickets/${eventId}/user/${userId}`,
        {
          method: 'GET',
          headers: {
            'accept': 'application/json',
            'X-API-KEY': this.config.apiKey,
            'Authorization': `Bearer ${accessToken}`,
          },
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to purchase ticket'
        throw new Error(errorMessage)
      }

      return await response.json()
    } catch (error) {
      console.error('Error purchasing ticket:', error)
      throw error
    }
  }

  async checkPaymentStatus(eventId: string, paymentHash: string): Promise<{ paid: boolean; ticket_id?: string }> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/events/api/v1/tickets/${eventId}/${paymentHash}`,
        {
          method: 'POST',
          headers: {
            'accept': 'application/json',
            'X-API-KEY': this.config.apiKey,
          },
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to check payment status'
        throw new Error(errorMessage)
      }

      return await response.json()
    } catch (error) {
      console.error('Error checking payment status:', error)
      throw error
    }
  }

  async fetchUserTickets(userId: string, accessToken: string): Promise<Ticket[]> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/events/api/v1/tickets/user/${userId}`,
        {
          headers: {
            'accept': 'application/json',
            'X-API-KEY': this.config.apiKey,
            'Authorization': `Bearer ${accessToken}`,
          },
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to fetch user tickets'
        throw new Error(errorMessage)
      }

      return await response.json()
    } catch (error) {
      console.error('Error fetching user tickets:', error)
      throw error
    }
  }

  async payInvoiceWithWallet(paymentRequest: string, adminKey: string): Promise<{ payment_hash: string; fee_msat: number; preimage: string }> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/api/v1/payments`,
        {
          method: 'POST',
          headers: {
            'accept': 'application/json',
            'Content-Type': 'application/json',
            'X-API-KEY': adminKey,
          },
          body: JSON.stringify({
            out: true,
            bolt11: paymentRequest,
          }),
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to pay invoice'
        throw new Error(errorMessage)
      }

      return await response.json()
    } catch (error) {
      console.error('Error paying invoice:', error)
      throw error
    }
  }

  async createEvent(eventData: CreateEventRequest, adminKey: string): Promise<Event> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/events/api/v1/events`,
        {
          method: 'POST',
          headers: {
            'accept': 'application/json',
            'Content-Type': 'application/json',
            'X-API-KEY': adminKey,
          },
          body: JSON.stringify(eventData),
        }
      )

      if (!response.ok) {
        const error = await response.json()
        const errorMessage = typeof error.detail === 'string' 
          ? error.detail 
          : error.detail[0]?.msg || 'Failed to create event'
        throw new Error(errorMessage)
      }

      return await response.json()
    } catch (error) {
      console.error('Error creating event:', error)
      throw error
    }
  }

  async getCurrencies(): Promise<string[]> {
    try {
      const response = await fetch(
        `${this.config.baseUrl}/api/v1/currencies`,
        {
          headers: {
            'accept': 'application/json',
          },
        }
      )

      if (!response.ok) {
        // If API call fails, return default currencies
        console.warn('Failed to fetch currencies from API, using defaults')
        return ['sats']
      }

      const apiCurrencies = await response.json()
      
      // Combine 'sats' with API currencies, following the pattern from market API
      if (Array.isArray(apiCurrencies)) {
        return ['sats', ...apiCurrencies.filter((currency: string) => currency !== 'sats')]
      }

      return ['sats']
    } catch (error) {
      console.error('Error fetching currencies:', error)
      return ['sats']
    }
  }
}