import axios, { AxiosError, AxiosInstance } from 'axios';
import { tokenUtils } from './auth-token';

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

// Create axios instance
const api: AxiosInstance = axios.create({
  baseURL: API_URL,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor to add auth token
api.interceptors.request.use(
  (config) => {
    const token = tokenUtils.get();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// Response interceptor for token refresh
api.interceptors.response.use(
  (response) => response,
  async (error: AxiosError) => {
    const originalRequest = error.config;
    
    if (error.response?.status === 401 && originalRequest) {
      const errorCode = (error.response.data as any)?.error?.code;
      
      if (errorCode === 'TOKEN_EXPIRED') {
        try {
          const refreshToken = localStorage.getItem('refresh_token');
          
          if (refreshToken) {
            const response = await axios.post(`${API_URL}/auth/refresh`, {
              refresh_token: refreshToken,
            });
            
            const { access_token, refresh_token } = response.data.data;
            
            tokenUtils.save(access_token);
            localStorage.setItem('refresh_token', refresh_token);
            
            originalRequest.headers.Authorization = `Bearer ${access_token}`;
            return api(originalRequest);
          }
        } catch (refreshError: any) {
          // Refresh failed. Only wipe tokens and redirect to login if the error is 400 (Bad Request) or 401 (Unauthorized).
          // Otherwise, it might be a transient network issue or 500 error, so we should not log the user out.
          if (refreshError.response?.status === 400 || refreshError.response?.status === 401) {
            tokenUtils.clear();
            window.location.href = '/login';
          }
        }
      }
    }
    
    return Promise.reject(error);
  }
);

// Auth API
export const authApi = {
  login: (email: string, password: string) =>
    api.post('/auth/login', { email, password }),
  
  register: (data: any) =>
    api.post('/auth/register', data),
  
  logout: () =>
    api.post('/auth/logout'),
  
  me: () =>
    api.get('/auth/me'),
  
  updateProfile: (data: any) =>
    api.put('/auth/me', data),
  
  changePassword: (currentPassword: string, newPassword: string) =>
    api.put('/auth/me/password', { current_password: currentPassword, new_password: newPassword }),
  
  forgotPassword: (email: string) =>
    api.post('/auth/forgot-password', { email }),
};

// Properties API
export const propertiesApi = {
  list: (params?: any) =>
    api.get('/properties', { params }),
  
  get: (id: string) =>
    api.get(`/properties/${id}`),
  
  create: (data: any) =>
    api.post('/properties', data),
  
  update: (id: string, data: any) =>
    api.put(`/properties/${id}`, data),
  
  delete: (id: string) =>
    api.delete(`/properties/${id}`),
  
  search: (query: string) =>
    api.get('/search/suggestions', { params: { q: query } }),
};

// Leads API
export const leadsApi = {
  list: (params?: any) =>
    api.get('/leads', { params }),
  
  get: (id: string) =>
    api.get(`/leads/${id}`),
  
  create: (data: any) =>
    api.post('/leads', data),
  
  updateStatus: (id: string, status: string, notes?: string) =>
    api.put(`/leads/${id}/status`, { status, notes }),
  
  assign: (id: string, agentId: number) =>
    api.post(`/leads/${id}/assign`, { agent_id: agentId }),
  
  addActivity: (id: string, data: any) =>
    api.post(`/leads/${id}/activities`, data),
  
  getAnalytics: () =>
    api.get('/leads/analytics'),
};

// Subscriptions API
export const subscriptionsApi = {
  getPlans: (targetRole?: string) =>
    api.get('/subscriptions/plans', { params: { target_role: targetRole } }),
  
  getCurrent: () =>
    api.get('/subscriptions/current'),
  
  checkout: (planId: number, billingCycle: 'monthly' | 'annual', successUrl: string, cancelUrl: string) =>
    api.post('/subscriptions/checkout', {
      plan_id: planId,
      billing_cycle: billingCycle,
      success_url: successUrl,
      cancel_url: cancelUrl,
    }),
  
  changePlan: (newPlanId: number) =>
    api.post('/subscriptions/change-plan', { new_plan_id: newPlanId }),
  
  cancel: (reason?: string) =>
    api.post('/subscriptions/cancel', { reason }),
  
  getInvoices: () =>
    api.get('/subscriptions/invoices'),
};

// Webinars API
export const webinarsApi = {
  list: (params?: any) =>
    api.get('/webinars', { params }),
  
  get: (id: string) =>
    api.get(`/webinars/${id}`),
  
  register: (id: string, data: any) =>
    api.post(`/webinars/${id}/register`, data),
  
  create: (data: any) =>
    api.post('/dev/webinars', data),
  
  getHostDashboard: (id: string) =>
    api.get(`/dev/webinars/${id}/dashboard`),
};

// Favorites API
export const favoritesApi = {
  list: () =>
    api.get('/me/favorites'),
  
  add: (unitId: number) =>
    api.post('/me/favorites', { unit_id: unitId }),
  
  remove: (id: number) =>
    api.delete(`/me/favorites/${id}`),
};

export default api;
