import axios from 'axios';
import { getToken, clearAuth } from './auth';

// Cached config to avoid repeated fetches
let cachedConfig: any = null;

/**
 * Fetches the network configuration from the public/network.json file.
 * This file is generated at startup by start_server.sh or docker-compose.
 */
export const getNetworkConfig = async () => {
    if (cachedConfig) return cachedConfig;

    if (typeof window === 'undefined') {
        return { SERVER_IP: 'localhost', BACKEND_PORT: 8000, BACKEND_SSL_PORT: 8908 };
    }

    try {
        const response = await fetch('/network.json');
        if (!response.ok) throw new Error("Config not found");
        cachedConfig = await response.json();
        return cachedConfig;
    } catch (e) {
        console.warn("Network config not found, using compiled defaults.");
        // Defaults matching the initial reserve ports in case network.json is missing
        return { SERVER_IP: 'localhost', BACKEND_PORT: 8906, BACKEND_SSL_PORT: 8908 };
    }
};

export const getBackendUrl = async () => {
  const config = await getNetworkConfig();
  
  if (typeof window === 'undefined') return `http://localhost:${config.BACKEND_PORT}`;

  const host = window.location.hostname;

  // If we are on HTTPS (Proxy/Mobile mode), we use the SSL port for the backend
  if (window.location.protocol === 'https:') {
    if (host.includes('.loca.lt')) {
       return 'https://inventory-ai-api.loca.lt';
    }
    return `https://${host}:${config.BACKEND_SSL_PORT}`;
  }

  return `http://${host}:${config.BACKEND_PORT}`;
};

/**
 * [C-01] Axios instance cu JWT Bearer token în header
 * și interceptor pentru 401 Unauthorized (token expired)
 */
const axiosInstance = axios.create({});

axiosInstance.interceptors.request.use(async (config) => {
  if (!config.baseURL) {
    config.baseURL = await getBackendUrl();  // called at request time — always correct
  }
  const token = getToken();
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, (error) => Promise.reject(error));

axiosInstance.interceptors.response.use(
  (response) => response,
  (error) => {
    // [L-01] Handle 401 Unauthorized — token expired
    if (error.response?.status === 401) {
      clearAuth();
      if (typeof window !== 'undefined' && !window.location.pathname.includes('/login')) {
        window.location.href = '/login';
      }
    }
    return Promise.reject(error);
  }
);

export const inventoryApi = {
  getItems: async () => {
    const res = await axiosInstance.get('/items/');
    return res.data;
  },

  getStats: async () => {
    const res = await axiosInstance.get('/items/stats');
    return res.data;
  },

  syncBulkOperations: async (userId: number, operations: any[]) => {
    try {
      const res = await axiosInstance.post('/operations/bulk-sync', {
        user_id: userId,
        operations: operations
      });
      return res.data;
    } catch (err: any) {
      console.error("Sync API Error:", err);
      if (err.response?.status === 404) {
         throw new Error(`404: Endpoint not found`);
      }
      throw err;
    }
  },

  analyzeLabel: async (formData: FormData, mode: string = "item") => {
    const res = await axiosInstance.post(`/items/extract-label?mode=${mode}`, formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    });
    return res.data;
  },

  createItem: async (userId: number, itemData: any) => {
    const res = await axiosInstance.post('/items/', itemData);
    return res.data;
  },

  updateItem: async (itemId: number, itemData: any) => {
    const res = await axiosInstance.put(`/items/${itemId}`, itemData);
    return res.data;
  },

  adjustStock: async (endpoint: string, data: any) => {
    const res = await axiosInstance.post(`/operations/${endpoint}`, data);
    return res.data;
  },

  deleteItem: async (itemId: number) => {
    const res = await axiosInstance.delete(`/items/${itemId}`);
    return res.data;
  },

  getAuditLogs: async (limit: number = 50) => {
    const res = await axiosInstance.get('/operations/logs', { params: { limit } });
    return res.data;
  },

  // Users
  getUsers: async () => {
    // [C-01] Public endpoint — use plain axios to avoid JWT interceptor
    const baseUrl = await getBackendUrl();
    const res = await axios.get(`${baseUrl}/users/`);
    return res.data;
  },

  createUser: async (userData: any) => {
    const res = await axiosInstance.post('/users/', userData);
    return res.data;
  },

  login: async (credentials: any) => {
    // [C-01] Login endpoint — NU adaug token header (login e public)
    const baseUrl = await getBackendUrl();
    const res = await axios.post(`${baseUrl}/users/login`, credentials);
    return res.data;
  },

  deleteUser: async (userId: number) => {
    const res = await axiosInstance.delete(`/users/${userId}`);
    return res.data;
  },

  updateUser: async (userId: number, data: any) => {
    const res = await axiosInstance.put(`/users/${userId}`, data);
    return res.data;
  },

  getLdapConfig: async () => {
    const res = await axiosInstance.get('/users/ldap-config');
    return res.data;
  },
  updateLdapConfig: async (config: any) => {
    const res = await axiosInstance.post('/users/ldap-config', config);
    return res.data;
  },
  testLdapConnection: async (config: any) => {
    const res = await axiosInstance.post('/users/test-ldap', config);
    return res.data;
  },

  // Categories
  getCategories: async () => {
    const res = await axiosInstance.get('/categories/');
    return res.data;
  },
  createCategory: async (data: any) => {
    const res = await axiosInstance.post('/categories/', data);
    return res.data;
  },
  updateCategory: async (id: number, data: any) => {
    const res = await axiosInstance.put(`/categories/${id}`, data);
    return res.data;
  },
  deleteCategory: async (id: number) => {
    const res = await axiosInstance.delete(`/categories/${id}`);
    return res.data;
  },

  // Database Management
  getDbBackups: async () => {
    const res = await axiosInstance.get('/admin/db/backups');
    return res.data;
  },
  getDbStats: async () => {
    const res = await axiosInstance.get('/admin/db/stats');
    return res.data;
  },
  triggerBackup: async () => {
    const res = await axiosInstance.post('/admin/db/backup');
    return res.data;
  },
  restoreDatabase: async (filename: string) => {
    const res = await axiosInstance.post('/admin/db/restore', { filename, confirm: true });
    return res.data;
  },
  getDbSettings: async () => {
    const res = await axiosInstance.get('/admin/db/settings');
    return res.data;
  },
  updateDbSettings: async (settings: any) => {
    const res = await axiosInstance.patch('/admin/db/settings', settings);
    return res.data;
  }
};
