import axios, { AxiosInstance, AxiosError } from 'axios';
import Cookies from 'js-cookie';

const TOKEN_KEY = 'ts_token';
const TOKEN_EXPIRY_DAYS = 1;

// -----------------------------------------------------------------------
// Axios instance
// -----------------------------------------------------------------------
const api: AxiosInstance = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL + '/api/v1',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  timeout: 15_000,
});

// Attach token from cookie on every request
api.interceptors.request.use((config) => {
  const token = Cookies.get(TOKEN_KEY);
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// Global error handling
api.interceptors.response.use(
  (res) => res,
  (error: AxiosError) => {
    if (error.response?.status === 401) {
      Cookies.remove(TOKEN_KEY);
      if (typeof window !== 'undefined') {
        window.location.href = '/auth/login';
      }
    }
    return Promise.reject(error);
  }
);

// -----------------------------------------------------------------------
// Token helpers
// -----------------------------------------------------------------------
export const setToken = (token: string): void => {
  Cookies.set(TOKEN_KEY, token, { expires: TOKEN_EXPIRY_DAYS, secure: true, sameSite: 'strict' });
};

export const removeToken = (): void => {
  Cookies.remove(TOKEN_KEY);
};

export const getToken = (): string | undefined => {
  return Cookies.get(TOKEN_KEY);
};

// -----------------------------------------------------------------------
// Auth API
// -----------------------------------------------------------------------
export const authApi = {
  login: (username: string, password: string) =>
    api.post('/auth/login', { username, password }),

  verifyOtp: (tempToken: string, otp: string, deviceName?: string) =>
    api.post('/auth/verify-otp', { temp_token: tempToken, otp, device_name: deviceName }),

  setup2fa: (tempToken: string, otp: string, deviceName?: string) =>
    api.post('/auth/setup-2fa', { temp_token: tempToken, otp, device_name: deviceName }),

  firstLoginSetup: (tempToken: string, payload: {
    new_password: string;
    new_password_confirmation: string;
    display_name: string;
    email: string;
  }) => api.post('/auth/first-login/setup', { temp_token: tempToken, ...payload }),

  logout: () => api.post('/auth/logout'),
  refresh: () => api.post('/auth/refresh'),
  me: () => api.get('/auth/me'),
};

// -----------------------------------------------------------------------
// Profile API
// -----------------------------------------------------------------------
export const profileApi = {
  get: () => api.get('/profile'),
  update: (data: { display_name?: string; email?: string; name?: string }) =>
    api.put('/profile', data),
  changePassword: (data: {
    current_password: string;
    new_password: string;
    new_password_confirmation: string;
  }) => api.put('/profile/password', data),
};

// -----------------------------------------------------------------------
// 2FA Device API
// -----------------------------------------------------------------------
export const twoFaApi = {
  devices: () => api.get('/2fa/devices'),
  addDevice: (otp: string, deviceName: string) =>
    api.post('/2fa/devices', { otp, device_name: deviceName }),
  removeDevice: (deviceId: string) =>
    api.delete(`/2fa/devices/${deviceId}`),
  reEnrol: () => api.post('/2fa/re-enrol'),
  confirmReEnrol: (otp: string, deviceName?: string) =>
    api.post('/2fa/confirm-re-enrol', { otp, device_name: deviceName }),
};

// -----------------------------------------------------------------------
// User Management API
// -----------------------------------------------------------------------
export const usersApi = {
  list: (params?: {
    role?: string;
    status?: string;
    search?: string;
    page?: number;
    per_page?: number;
  }) => api.get('/users', { params }),

  get: (id: number) => api.get(`/users/${id}`),

  create: (data: {
    username: string;
    name: string;
    email: string;
    password: string;
    role: 'admin' | 'operator';
  }) => api.post('/users', data),

  update: (id: number, data: {
    name?: string;
    email?: string;
    status?: string;
  }) => api.put(`/users/${id}`, data),

  delete: (id: number) => api.delete(`/users/${id}`),

  updateStatus: (id: number, status: 'active' | 'disabled') =>
    api.post(`/users/${id}/status`, { status }),

  resetPassword: (id: number, newPassword: string, confirmation: string) =>
    api.post(`/users/${id}/reset-password`, {
      new_password: newPassword,
      new_password_confirmation: confirmation,
    }),
};

export default api;
