import axios from 'axios';

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3020/api/v1';

class ApiClient {
  private token: string | null = null;
  private refreshToken: string | null = null;

  constructor() {
    // Initialize tokens from localStorage if available
    if (typeof window !== 'undefined') {
      this.token = localStorage.getItem('admin_access_token');
      this.refreshToken = localStorage.getItem('admin_refresh_token');
    }
  }

  setTokens(accessToken: string, refreshToken: string) {
    this.token = accessToken;
    this.refreshToken = refreshToken;
    if (typeof window !== 'undefined') {
      localStorage.setItem('admin_access_token', accessToken);
      localStorage.setItem('admin_refresh_token', refreshToken);
    }
  }

  clearTokens() {
    this.token = null;
    this.refreshToken = null;
    if (typeof window !== 'undefined') {
      localStorage.removeItem('admin_access_token');
      localStorage.removeItem('admin_refresh_token');
    }
  }

  private async request(method: string, endpoint: string, data?: any, options?: any) {
    const config = {
      method,
      url: `${API_BASE_URL}${endpoint}`,
      headers: {
        'Content-Type': 'application/json',
        ...(this.token ? { Authorization: `Bearer ${this.token}` } : {}),
        ...options?.headers,
      },
      ...options,
    };

    if (data) {
      config.data = data;
    }

    try {
      const response = await axios(config);
      return response.data;
    } catch (error: any) {
      // Handle token refresh
      if (error.response?.status === 401 && this.refreshToken) {
        try {
          const refreshResponse = await axios.post(`${API_BASE_URL}/auth/refresh`, {
            refreshToken: this.refreshToken,
          });

          this.setTokens(refreshResponse.data.accessToken, refreshResponse.data.refreshToken);

          // Retry original request
          config.headers.Authorization = `Bearer ${this.token}`;
          const response = await axios(config);
          return response.data;
        } catch (refreshError) {
          this.clearTokens();
          window.location.href = '/login';
          throw refreshError;
        }
      }
      throw error;
    }
  }

  // Generic HTTP methods
  async get(endpoint: string, options?: any) {
    return this.request('GET', endpoint, undefined, options);
  }

  async post(endpoint: string, data?: any, options?: any) {
    return this.request('POST', endpoint, data, options);
  }

  async patch(endpoint: string, data?: any, options?: any) {
    return this.request('PATCH', endpoint, data, options);
  }

  async put(endpoint: string, data?: any, options?: any) {
    return this.request('PUT', endpoint, data, options);
  }

  async delete(endpoint: string, options?: any) {
    return this.request('DELETE', endpoint, undefined, options);
  }

  // Auth endpoints
  async login(email: string, password: string) {
    // Generate device info for admin dashboard
    const deviceInfo = {
      deviceId: this.getOrCreateDeviceId(),
      platform: 'web',
      model: 'Admin Dashboard',
      osVersion: navigator.userAgent,
    };

    const response = await this.request('POST', '/auth/login', {
      email,
      password,
      deviceInfo
    });

    // Extract tokens from nested response structure
    const tokens = response.tokens || response.data?.tokens;
    if (tokens?.accessToken && tokens?.refreshToken) {
      this.setTokens(tokens.accessToken, tokens.refreshToken);
    }

    return response;
  }

  private getOrCreateDeviceId(): string {
    if (typeof window === 'undefined') return 'server';

    let deviceId = localStorage.getItem('admin_device_id');
    if (!deviceId) {
      deviceId = 'admin_' + Math.random().toString(36).substring(2) + Date.now().toString(36);
      localStorage.setItem('admin_device_id', deviceId);
    }
    return deviceId;
  }

  async logout() {
    try {
      // Only try to call logout endpoint if we have a token
      if (this.token) {
        await this.request('POST', '/auth/logout');
      }
    } catch (error) {
      // Ignore errors on logout - we'll clear tokens anyway
      console.log('Logout request failed, clearing tokens locally');
    } finally {
      this.clearTokens();
    }
  }

  isAuthenticated(): boolean {
    return !!this.token;
  }

  async getCurrentAdmin() {
    return this.request('GET', '/auth/me');
  }

  // User management endpoints
  async getUsers(params?: { page?: number; limit?: number; search?: string }) {
    const queryString = params ? '?' + new URLSearchParams(params as any).toString() : '';
    return this.request('GET', `/admin/users${queryString}`);
  }

  async getUserById(id: string) {
    return this.request('GET', `/admin/users/${id}`);
  }

  async updateUser(id: string, data: any) {
    return this.request('PATCH', `/admin/users/${id}`, data);
  }

  async deleteUser(id: string) {
    return this.request('DELETE', `/admin/users/${id}`);
  }

  // Invite code endpoints
  async getInviteCodes(params?: { page?: number; limit?: number; status?: string }) {
    const queryString = params ? '?' + new URLSearchParams(params as any).toString() : '';
    return this.request('GET', `/admin/invite-codes${queryString}`);
  }

  async createInviteCode(data: {
    code: string;
    maxUses?: number;
    expiresAt?: string;
    metadata?: any;
  }) {
    return this.request('POST', '/admin/invite-codes', data);
  }

  async updateInviteCode(id: string, data: any) {
    return this.request('PATCH', `/admin/invite-codes/${id}`, data);
  }

  async deleteInviteCode(id: string) {
    return this.request('DELETE', `/admin/invite-codes/${id}`);
  }

  // Analytics endpoints
  async getAnalytics(params?: { startDate?: string; endDate?: string }) {
    const queryString = params ? '?' + new URLSearchParams(params as any).toString() : '';
    return this.request('GET', `/admin/analytics${queryString}`);
  }

  async getUserGrowth() {
    return this.request('GET', '/admin/analytics/user-growth');
  }

  async getActivityStats() {
    return this.request('GET', '/admin/analytics/activity-stats');
  }

  async getSystemHealth() {
    return this.request('GET', '/admin/analytics/system-health');
  }

  // Family management
  async getFamilies(params?: { page?: number; limit?: number; search?: string }) {
    const queryString = params ? '?' + new URLSearchParams(params as any).toString() : '';
    return this.request('GET', `/admin/families${queryString}`);
  }

  async getFamilyById(id: string) {
    return this.request('GET', `/admin/families/${id}`);
  }

  // Activity logs
  async getActivityLogs(params?: { page?: number; limit?: number; userId?: string }) {
    const queryString = params ? '?' + new URLSearchParams(params as any).toString() : '';
    return this.request('GET', `/admin/logs${queryString}`);
  }

  // System settings
  async getSettings() {
    return this.request('GET', '/admin/settings');
  }

  async updateSettings(data: any) {
    return this.request('PATCH', '/admin/settings', data);
  }
}

export const apiClient = new ApiClient();
export default apiClient;