import AsyncStorage from '@react-native-async-storage/async-storage';

const API_BASE_URL = 'http://localhost:3001/api';
const USE_MOCK_DATA = false; // Set to false to use real database

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 AsyncStorage.getItem('golap_token');
    } catch (error) {
      console.error('Error loading token:', error);
    }
  }

  private async saveToken(token: string) {
    try {
      this.token = token;
      await AsyncStorage.setItem('golap_token', token);
    } catch (error) {
      console.error('Error saving token:', error);
    }
  }

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

  private async getUserStatistics() {
    try {
      // Use token as unique identifier for user statistics
      const statsKey = this.token ? `stats_${this.token.slice(-10)}` : 'stats_anonymous';
      const stats = await AsyncStorage.getItem(`golap_${statsKey}`);
      return stats ? JSON.parse(stats) : {
        betriebstechnik: { total: 0, richtig: 0, falsch: 0, bestScore: 0 },
        applikationsentwicklung: { total: 0, richtig: 0, falsch: 0, bestScore: 0 }
      };
    } catch (error) {
      console.error('Error loading user statistics:', error);
      return {
        betriebstechnik: { total: 0, richtig: 0, falsch: 0, bestScore: 0 },
        applikationsentwicklung: { total: 0, richtig: 0, falsch: 0, bestScore: 0 }
      };
    }
  }

  private async saveUserStatistics(stats: any) {
    try {
      const statsKey = this.token ? `stats_${this.token.slice(-10)}` : 'stats_anonymous';
      await AsyncStorage.setItem(`golap_${statsKey}`, JSON.stringify(stats));
    } catch (error) {
      console.error('Error saving user statistics:', error);
    }
  }

  private async getUserQuizHistory() {
    try {
      const historyKey = this.token ? `history_${this.token.slice(-10)}` : 'history_anonymous';
      const history = await AsyncStorage.getItem(`golap_${historyKey}`);
      return history ? JSON.parse(history) : [];
    } catch (error) {
      console.error('Error loading quiz history:', error);
      return [];
    }
  }

  private async saveQuizHistory(history: any) {
    try {
      const historyKey = this.token ? `history_${this.token.slice(-10)}` : 'history_anonymous';
      await AsyncStorage.setItem(`golap_${historyKey}`, JSON.stringify(history));
    } catch (error) {
      console.error('Error saving quiz history:', error);
    }
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    console.log('API Request:', endpoint, 'USE_MOCK_DATA:', USE_MOCK_DATA);
    
    // Use real database when USE_MOCK_DATA is false
    if (USE_MOCK_DATA) {
      console.log('Using mock data for:', endpoint);
      return this.getMockResponse<T>(endpoint);
    }

    const url = `${API_BASE_URL}${endpoint}`;
    console.log('Making request to:', url);
    
    const headers: HeadersInit = {
      'Content-Type': 'application/json',
    };

    if (this.token) {
      headers.Authorization = `Bearer ${this.token}`;
      console.log('Using token:', this.token);
    } else {
      console.log('No token found');
    }

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

      const data = await response.json();
      console.log('API Response status:', response.status, 'data:', data);
      console.log('Response type:', typeof data);

      if (!response.ok) {
        console.log('Response not OK, status:', response.status);
        // If token is invalid, clear it and fallback to mock
        if (response.status === 401 && data.error?.includes('Token')) {
          console.log('Token invalid, clearing and falling back to mock data');
          await this.removeToken();
          return this.getMockResponse<T>(endpoint);
        }
        throw new Error(data.error || 'Request failed');
      }

      return data;
    } catch (error: any) {
      console.error('API Request Error:', error);
      console.log('Error type:', error.name);
      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');
        console.log('Falling back to mock data...');
        return this.getMockResponse<T>(endpoint);
      }
      
      // Fallback to mock data if backend is not available
      console.log('Falling back to mock data...');
      return this.getMockResponse<T>(endpoint);
    }
  }

  private getMockResponse<T>(endpoint: string): ApiResponse<T> {
    if (endpoint.includes('/login')) {
      return {
        user: { 
          id: 1, 
          email: 'test@example.com', 
          username: 'testuser', 
          firstName: 'Test', 
          lastName: 'User',
          created_at: new Date('2024-01-01').toISOString()
        },
        token: 'mock-token-123',
        message: 'Login successful (mock)'
      };
    }
    
    if (endpoint.includes('/register')) {
      return {
        user: { 
          id: 2, 
          email: 'new@example.com', 
          username: 'newuser', 
          firstName: 'New', 
          lastName: 'User',
          created_at: new Date().toISOString()
        },
        token: 'mock-token-456',
        message: 'Registration successful (mock)'
      };
    }
    
    if (endpoint.includes('/profile')) {
      return {
        user: { 
          id: 1, 
          email: 'test@example.com', 
          username: 'testuser', 
          firstName: 'Test', 
          lastName: 'User',
          created_at: new Date('2024-01-01').toISOString()
        }
      };
    }
    
    if (endpoint.includes('/questions')) {
      // Generate random questions for each profession
      const questions = [];
      
      if (endpoint.includes('betriebstechnik')) {
        const betriebQuestions = [
          {
            id: 1,
            frage: 'Was ist die Hauptaufgabe der ergonomischen Gestaltung eines Arbeitsplatzes?',
            antworten: ['Die Produktivität zu maximieren', 'Die Gesundheit und das Wohlbefinden des Mitarbeiters zu fördern', 'Die Kosten zu minimieren', 'Den Platz zu sparen'],
            richtigeAntwort: 1,
            kategorie: 'Arbeitsplatzgestaltung'
          },
          {
            id: 2,
            frage: 'Welche Schutzart wird bei Arbeiten an elektrischen Anlagen unter 50V Wechselspannung verwendet?',
            antworten: ['Schutzkleinspannung', 'Schutzisolierung', 'Schutzerdung', 'Schutzpotentialausgleich'],
            richtigeAntwort: 0,
            kategorie: 'Elektrische Sicherheit'
          }
        ];
        
        // Shuffle and return requested amount
        const shuffled = betriebQuestions.sort(() => Math.random() - 0.5);
        const questionCount = Math.min(20, Math.max(15, shuffled.length));
        return { data: shuffled.slice(0, questionCount) } as ApiResponse<T>;
      }
      
      if (endpoint.includes('applikationsentwicklung')) {
        const appQuestions = [
          {
            id: 1,
            frage: 'Was ist React Native?',
            antworten: ['Ein Framework', 'Eine Programmiersprache', 'Ein Betriebssystem', 'Eine Datenbank'],
            richtigeAntwort: 0,
            kategorie: 'Grundlagen'
          },
          {
            id: 2,
            frage: 'Welche Sprache wird für iOS-Apps verwendet?',
            antworten: ['Java', 'Swift', 'Kotlin', 'C#'],
            richtigeAntwort: 1,
            kategorie: 'Mobile Entwicklung'
          }
        ];
        
        // Shuffle and return requested amount
        const shuffled = appQuestions.sort(() => Math.random() - 0.5);
        const questionCount = Math.min(20, Math.max(15, shuffled.length));
        return { data: shuffled.slice(0, questionCount) } as ApiResponse<T>;
      }
      
      return { data: [] as any } as ApiResponse<T>;
    }
    
    if (endpoint.includes('/categories')) {
      return {
        data: ['Grundlagen', 'Tools', 'Programmierung', 'Datenbanken'] as any
      } as ApiResponse<T>;
    }
    
    if (endpoint.includes('/statistics')) {
      // Return empty statistics for new users - real data comes from AsyncStorage
      return {
        data: {
          betriebstechnik: { 
            total: 0, 
            richtig: 0, 
            falsch: 0,
            bestScore: 0
          },
          applikationsentwicklung: { 
            total: 0, 
            richtig: 0, 
            falsch: 0,
            bestScore: 0
          }
        } as any
      } as ApiResponse<T>;
    }
    
    if (endpoint.includes('/statistics/reset')) {
      return {
        data: {
          betriebstechnik: { 
            total: 0, 
            richtig: 0, 
            falsch: 0,
            bestScore: 0
          },
          applikationsentwicklung: { 
            total: 0, 
            richtig: 0, 
            falsch: 0,
            bestScore: 0
          }
        } as any
      } as ApiResponse<T>;
    }
    
    if (endpoint.includes('/quiz/history')) {
      return {
        data: [
          {
            id: 1,
            date: '2024-01-15',
            beruf: 'applikationsentwicklung',
            score: 85,
            totalQuestions: 20
          }
        ] as any
      } as ApiResponse<T>;
    }
    
    if (endpoint.includes('/statistics/update')) {
      return {
        success: true,
        message: 'Statistics updated successfully'
      };
    }
    
    return { data: null } as ApiResponse<T>;
  }

  // Auth Methods
  async login(email: string, password: string) {
    const response = await this.request('/auth/login', {
      method: 'POST',
      body: JSON.stringify({ email, password }),
    });

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

    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)}`;
    }
    return this.request(endpoint);
  }

  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:', profileResponse);
    // Extract statistics from profile response
    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('/user/statistics/update', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }

  async getQuizHistory(beruf?: string) {
    let endpoint = '/user/quiz/history';
    if (beruf) {
      endpoint += `?beruf=${beruf}`;
    }
    return this.request(endpoint);
  }

  // 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;
