const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5000/api';

// Types
export interface User {
  id: string;
  email: string;
  name: string;
  role: 'Organizer' | 'Participant';
}

export interface AuthResponse {
  token: string;
  user: User;
}

export interface Event {
  id: string;
  name: string;
  description: string;
  eventDate: string;
  location: string;
  status: 'Draft' | 'Published' | 'Cancelled' | 'Completed';
  category?: string;
  tags: string[];
  maxParticipants?: number;
  currentRegistrations: number;
  createdAt: string;
  updatedAt: string;
  organizer: User;
}

export interface Registration {
  id: string;
  eventId: string;
  eventName: string;
  eventDate: string;
  participantId: string;
  participantName: string;
  participantEmail: string;
  status: string;
  category?: string;
  emergencyContact?: string;
  createdAt: string;
  updatedAt?: string;
  totalPaid: number;
  amountDue: number;
}

export interface Announcement {
  id: string;
  eventId: string;
  eventName: string;
  title: string;
  content: string;
  authorId: string;
  authorName: string;
  createdAt: string;
  updatedAt?: string;
  isPublished: boolean;
}

export interface PaymentReport {
  eventId: string;
  eventName: string;
  totalCollected: number;
  totalPending: number;
  totalOutstanding: number;
  totalRegistrations: number;
  paidRegistrations: number;
  partialRegistrations: number;
  unpaidRegistrations: number;
}

// API Client
class ApiClient {
  private token: string | null = null;

  constructor() {
    if (typeof window !== 'undefined') {
      this.token = localStorage.getItem('token');
    }
  }

  setToken(token: string) {
    this.token = token;
    if (typeof window !== 'undefined') {
      localStorage.setItem('token', token);
    }
  }

  clearToken() {
    this.token = null;
    if (typeof window !== 'undefined') {
      localStorage.removeItem('token');
    }
  }

  getToken(): string | null {
    return this.token;
  }

  private async fetch(endpoint: string, options: RequestInit = {}) {
    const url = `${API_URL}${endpoint}`;
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      ...((options.headers as Record<string, string>) || {}),
    };

    if (this.token) {
      headers['Authorization'] = `Bearer ${this.token}`;
    }

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

    if (!response.ok) {
      const error = await response.json().catch(() => ({ error: 'Unknown error' }));
      throw new Error(error.error || `HTTP ${response.status}`);
    }

    if (response.status === 204) {
      return null;
    }

    return response.json();
  }

  // Auth
  async register(email: string, password: string, name: string, role: 'Organizer' | 'Participant' = 'Participant') {
    const data = await this.fetch('/auth/register', {
      method: 'POST',
      body: JSON.stringify({ email, password, name, role }),
    });
    this.setToken(data.token);
    return data as AuthResponse;
  }

  async login(email: string, password: string) {
    const data = await this.fetch('/auth/login', {
      method: 'POST',
      body: JSON.stringify({ email, password }),
    });
    this.setToken(data.token);
    return data as AuthResponse;
  }

  logout() {
    this.clearToken();
  }

  // Events
  async getEvents(filters?: { category?: string; status?: string; fromDate?: string; toDate?: string }) {
    const params = new URLSearchParams();
    if (filters?.category) params.append('category', filters.category);
    if (filters?.status) params.append('status', filters.status);
    if (filters?.fromDate) params.append('fromDate', filters.fromDate);
    if (filters?.toDate) params.append('toDate', filters.toDate);
    
    const query = params.toString();
    return this.fetch(`/events${query ? `?${query}` : ''}`) as Promise<Event[]>;
  }

  async getEvent(id: string) {
    return this.fetch(`/events/${id}`) as Promise<Event>;
  }

  async createEvent(event: Partial<Event>) {
    return this.fetch('/events', {
      method: 'POST',
      body: JSON.stringify(event),
    }) as Promise<Event>;
  }

  async updateEvent(id: string, event: Partial<Event>) {
    return this.fetch(`/events/${id}`, {
      method: 'PUT',
      body: JSON.stringify(event),
    }) as Promise<Event>;
  }

  async deleteEvent(id: string) {
    return this.fetch(`/events/${id}`, {
      method: 'DELETE',
    });
  }

  // Registrations
  async createRegistration(eventId: string, category?: string, emergencyContact?: string) {
    return this.fetch('/registrations', {
      method: 'POST',
      body: JSON.stringify({ eventId, category, emergencyContact }),
    }) as Promise<Registration>;
  }

  async getMyRegistrations() {
    return this.fetch('/registrations/my-registrations') as Promise<Registration[]>;
  }

  async getEventRegistrations(eventId: string) {
    return this.fetch(`/registrations/event/${eventId}`) as Promise<Registration[]>;
  }

  async cancelRegistration(id: string) {
    return this.fetch(`/registrations/${id}/cancel`, {
      method: 'POST',
    }) as Promise<Registration>;
  }

  // Payments
  async recordPayment(registrationId: string, amount: number, method: string, transactionId?: string, notes?: string) {
    return this.fetch('/payments', {
      method: 'POST',
      body: JSON.stringify({ registrationId, amount, method, transactionId, notes }),
    });
  }

  async getPaymentReport(eventId: string) {
    return this.fetch(`/payments/event/${eventId}/report`) as Promise<PaymentReport>;
  }

  // Announcements
  async getEventAnnouncements(eventId: string) {
    return this.fetch(`/announcements/event/${eventId}`) as Promise<Announcement[]>;
  }

  async createAnnouncement(eventId: string, title: string, content: string) {
    return this.fetch('/announcements', {
      method: 'POST',
      body: JSON.stringify({ eventId, title, content }),
    }) as Promise<Announcement>;
  }

  // Dashboard
  async getOrganizerDashboard() {
    return this.fetch('/dashboard/organizer');
  }

  async getParticipantDashboard() {
    return this.fetch('/dashboard/participant');
  }
}

export const api = new ApiClient();