import { supabase } from './supabase';
import type { Database } from './database.types';

export interface ApiResponse<T> {
  data: T | null;
  error: string | null;
  success: boolean;
}

export interface EventStats {
  ticketsSold: number;
  ticketsAvailable: number;
  checkedIn: number;
  totalRevenue: number;
  netRevenue: number;
}

export interface EventDetails {
  id: string;
  title: string;
  description: string;
  venue: string;
  start_time: string;
  slug: string;
  organization_id: string;
}

class ApiClient {
  private authenticated = false;
  private session: any = null;
  private userOrganizationId: string | null = null;

  async initialize(): Promise<boolean> {
    try {

      const { data: { session }, error: sessionError } = await supabase.auth.getSession();
      
      if (sessionError) {

        this.authenticated = false;
        return false;
      }
      
      if (!session) {

        this.authenticated = false;
        return false;
      }

      this.session = session;
      this.authenticated = true;

      // Get user's organization
      const { data: userRecord, error: userError } = await supabase
        .from('users')
        .select('organization_id')
        .eq('id', session.user.id)
        .single();

      if (userError) {

      }

      this.userOrganizationId = userRecord?.organization_id || null;

      return true;
    } catch (error) {

      this.authenticated = false;
      return false;
    }
  }

  private async ensureAuthenticated(): Promise<boolean> {
    if (!this.authenticated) {
      const initialized = await this.initialize();
      if (!initialized) {

        // Don't automatically redirect here - let the component handle it
        return false;
      }
    }
    return true;
  }

  async getEventDetails(eventId: string): Promise<ApiResponse<EventDetails>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data: event, error } = await supabase
        .from('events')
        .select('*')
        .eq('id', eventId)
        .single();

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: event, error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load event details', success: false };
    }
  }

  async getEventStats(eventId: string): Promise<ApiResponse<EventStats>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      // Load ticket sales data
      const { data: tickets, error: ticketsError } = await supabase
        .from('tickets')
        .select(`
          id,
          price,
          checked_in,
          refund_status,
          ticket_types (
            id,
            quantity_available
          )
        `)
        .eq('event_id', eventId);

      if (ticketsError) {

        return { data: null, error: ticketsError.message, success: false };
      }

      // Load ticket types for capacity calculation
      const { data: ticketTypes, error: ticketTypesError } = await supabase
        .from('ticket_types')
        .select('id, quantity_available')
        .eq('event_id', eventId)
        .eq('is_active', true);

      if (ticketTypesError) {

        return { data: null, error: ticketTypesError.message, success: false };
      }

      // Calculate stats
      const ticketsSold = tickets?.length || 0;
      // Only count non-refunded tickets for revenue
      const activeTickets = tickets?.filter(ticket => 
        !ticket.refund_status || ticket.refund_status === null
      ) || [];
      const totalRevenue = activeTickets.reduce((sum, ticket) => sum + ticket.price, 0) || 0;
      const netRevenue = totalRevenue * 0.97; // Assuming 3% platform fee
      const checkedIn = tickets?.filter(ticket => ticket.checked_in).length || 0;
      const totalCapacity = ticketTypes?.reduce((sum, type) => sum + type.quantity_available, 0) || 0;
      const ticketsAvailable = totalCapacity - ticketsSold;

      const stats: EventStats = {
        ticketsSold,
        ticketsAvailable,
        checkedIn,
        totalRevenue,
        netRevenue
      };

      return { data: stats, error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load event statistics', success: false };
    }
  }

  async getTicketTypes(eventId: string): Promise<ApiResponse<any[]>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data, error } = await supabase
        .from('ticket_types')
        .select('*')
        .eq('event_id', eventId)
        .eq('is_active', true)
        .order('display_order', { ascending: true });

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: data || [], error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load ticket types', success: false };
    }
  }

  async getOrders(eventId: string): Promise<ApiResponse<any[]>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data, error } = await supabase
        .from('tickets')
        .select(`
          *,
          ticket_types (
            name,
            price
          )
        `)
        .eq('event_id', eventId)
        .order('created_at', { ascending: false });

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: data || [], error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load orders', success: false };
    }
  }

  async getPresaleCodes(eventId: string): Promise<ApiResponse<any[]>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data, error } = await supabase
        .from('presale_codes')
        .select('*')
        .eq('event_id', eventId)
        .order('created_at', { ascending: false });

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: data || [], error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load presale codes', success: false };
    }
  }

  async getDiscountCodes(eventId: string): Promise<ApiResponse<any[]>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data, error } = await supabase
        .from('discount_codes')
        .select('*')
        .eq('event_id', eventId)
        .order('created_at', { ascending: false });

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: data || [], error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load discount codes', success: false };
    }
  }

  async getAttendees(eventId: string): Promise<ApiResponse<any[]>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const { data, error } = await supabase
        .from('tickets')
        .select(`
          *,
          ticket_types (
            name
          )
        `)
        .eq('event_id', eventId)
        .is('refund_status', null)
        .order('created_at', { ascending: false });

      if (error) {

        return { data: null, error: error.message, success: false };
      }

      return { data: data || [], error: null, success: true };
    } catch (error) {

      return { data: null, error: 'Failed to load attendees', success: false };
    }
  }

  // Utility methods
  getUserOrganizationId(): string | null {
    return this.userOrganizationId;
  }

  getUser(): any {
    return this.session?.user || null;
  }

  getSession(): any {
    return this.session;
  }

  isAuthenticated(): boolean {
    return this.authenticated;
  }

  async logout(): Promise<void> {
    await supabase.auth.signOut();
    this.authenticated = false;
    this.session = null;
    this.userOrganizationId = null;
  }

  // Generic authenticated request helper
  async makeAuthenticatedRequest<T>(
    url: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    try {
      if (!(await this.ensureAuthenticated())) {
        return { data: null, error: 'Authentication required', success: false };
      }

      const response = await fetch(url, {
        ...options,
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.session?.access_token}`,
          ...options.headers,
        },
      });

      if (!response.ok) {
        const errorText = await response.text();
        return {
          data: null,
          error: errorText || `HTTP ${response.status}`,
          success: false
        };
      }

      const data = await response.json();
      return { data, error: null, success: true };
    } catch (error) {
      return {
        data: null,
        error: error instanceof Error ? error.message : 'Request failed',
        success: false
      };
    }
  }
}

// Export a singleton instance
export const apiClient = new ApiClient();

// Export a hook-like function for easier use in components
export async function useApi() {
  if (!apiClient.isAuthenticated()) {
    await apiClient.initialize();
  }
  return apiClient;
}

// Export the makeAuthenticatedRequest function for direct use
export async function makeAuthenticatedRequest<T>(
  url: string,
  options: RequestInit = {}
): Promise<ApiResponse<T>> {
  return apiClient.makeAuthenticatedRequest<T>(url, options);
}