import Storage from './storage';

const API_BASE_URL = 'http://194.62.1.117:3001/api';

interface ApiResponse<T = any> {
  message?: string;
  user?: any;
  token?: string;
  data?: T;
  error?: string;
  success?: boolean;
}

class ApiService {
  private token: string | null = null;

  constructor() {
    this.loadToken();
  }

  private async loadToken() {
    try {
      this.token = await Storage.getItem('golap_token');
      console.log('Token loaded from Storage:', this.token ? 'YES' : 'NO');
    } catch (error) {
      console.error('Error loading token:', error);
    }
  }

  private async saveToken(token: string) {
    try {
      this.token = token;
      await Storage.setItem('golap_token', token);
      console.log('Token saved to Storage successfully');
    } catch (error) {
      console.error('Error saving token:', error);
    }
  }

  private async removeToken() {
    try {
      this.token = null;
      await Storage.removeItem('golap_token');
      console.log('Token removed from Storage');
    } catch (error) {
      console.error('Error removing token:', error);
    }
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    console.log('API Request:', endpoint);
    
    const url = `${API_BASE_URL}${endpoint}`;
    console.log('Making request to:', url);
    
    const headers: HeadersInit = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    };

    if (this.token) {
      headers.Authorization = `Bearer ${this.token}`;
      console.log('Using token for authenticated request');
    } else {
      console.log('No token found - making unauthenticated request');
    }

    try {
      console.log('Request options:', { method: options.method || 'GET', body: options.body });
      
      const response = await fetch(url, {
        ...options,
        headers,
      });

      console.log('API Response status:', response.status);

      const data = await response.json();

      if (!response.ok) {
        console.log('Response not OK, status:', response.status);
        console.log('Error data:', data);
        // If token is invalid, clear it
        if (response.status === 401 && data.error?.includes('Token')) {
          console.log('Token invalid, clearing token');
          await this.removeToken();
        }
        throw new Error(data.error || data.message || 'Request failed');
      }

      return data;
    } catch (error: any) {
      console.error('API Request Error:', error);
      console.log('Error message:', error.message);
      console.log('Make sure your backend server is running at:', API_BASE_URL);
      
      // Check if it's a JSON parse error
      if (error instanceof SyntaxError) {
        console.log('JSON Parse Error detected - Backend returning HTML instead of JSON');
        throw new Error('Backend server error - invalid response format');
      }
      
      // Re-throw the error for proper handling
      throw error;
    }
  }

  // Auth Methods
  async login(email: string, password: string) {
    console.log('Login attempt with:', { email, password: '***' });
    
    // Validierung
    if (!email || !password) {
      throw new Error('Email and password are required');
    }

    const response = await this.request('/auth/login', {
      method: 'POST',
      body: JSON.stringify({ 
        username: email.trim(),  // Backend erwartet "username" Feld
        password: password.trim() 
      }),
    });

    console.log('Login API response:', response);

    if (response.token) {
      console.log('Saving token to Storage...');
      await this.saveToken(response.token);
      console.log('Token saved successfully');
    } else {
      console.log('No token in response!');
    }

    return response;
  }

  async register(userData: {
    email: string;
    username: string;
    firstName: string;
    lastName: string;
    password: string;
  }) {
    const response = await this.request('/auth/register', {
      method: 'POST',
      body: JSON.stringify(userData),
    });

    if (response.token) {
      await this.saveToken(response.token);
    }

    return response;
  }

  async logout() {
    await this.removeToken();
  }

  // User Methods
  async getUserProfile() {
    return this.request('/user/profile');
  }

  async updateProfile(userData: any) {
    return this.request('/user/profile', {
      method: 'PUT',
      body: JSON.stringify(userData),
    });
  }

  // Questions Methods
  async getQuestions(beruf: string, limit: number = 10, category?: string) {
    let endpoint = `/questions/${beruf}?limit=${limit}`;
    if (category) {
      endpoint += `&category=${encodeURIComponent(category)}`;
    }
    console.log('Getting questions from:', endpoint);
    const response = await this.request(endpoint);
    console.log('Questions API response:', response);
    return response;
  }

  async getCategories(beruf: string) {
    return this.request(`/categories/${beruf}`);
  }

  // Statistics Methods
  async getProfile() {
    return this.request('/user/profile');
  }

  async getStatistics() {
    const profileResponse = await this.request('/user/profile');
    console.log('Profile response for statistics:', profileResponse);
    const stats = (profileResponse as any).statistics || {};
    console.log('Extracted statistics:', stats);
    return { data: stats };
  }

  async resetStatistics() {
    return this.request('/user/statistics/reset', {
      method: 'POST',
    });
  }

  async updateStatistics(data: {
    beruf: string;
    correct: number;
    wrong: number;
    sessionId?: string;
  }) {
    return this.request('/statistics/update', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }

  async getQuizHistory(beruf?: string) {
    let endpoint = '/user/quiz/history';
    if (beruf) {
      endpoint += `?beruf=${beruf}`;
    }
    console.log('Getting quiz history from:', endpoint);
    const response = await this.request(endpoint);
    console.log('Quiz history API response:', response);
    return response;
  }

  async getLeaderboard(beruf?: string, limit: number = 10) {
    let endpoint = '/leaderboard';
    const params = new URLSearchParams();
    if (beruf) params.append('beruf', beruf);
    params.append('limit', limit.toString());
    
    if (params.toString()) {
      endpoint += `?${params.toString()}`;
    }
    
    console.log('Getting leaderboard from:', endpoint);
    const response = await this.request(endpoint);
    console.log('Leaderboard API response:', response);
    return response;
  }

  // Helper Methods
  isAuthenticated(): boolean {
    return this.token !== null;
  }

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

  async clearToken(): Promise<void> {
    await this.removeToken();
  }
}

export const apiService = new ApiService();
export default apiService;
