import axios, { AxiosError, type InternalAxiosRequestConfig } from 'axios'
import { getAccessToken, refreshTokens, clearTokens } from './auth'

export const api = axios.create({
  baseURL: '',
  headers: { 'Content-Type': 'application/json' },
})

api.interceptors.request.use((config: InternalAxiosRequestConfig) => {
  const token = getAccessToken()
  if (token) {
    config.headers.set('Authorization', `Bearer ${token}`)
  }
  // SuperAdmin «открыть как…»: добавляем X-Org-Override на каждый запрос если
  // в localStorage активна выбранная орга (и эндпоинт не сам super-admin).
  const asOrg = getOrgOverride()
  if (asOrg && !(config.url ?? '').startsWith('/api/super-admin/')) {
    config.headers.set('X-Org-Override', asOrg.id)
    const edit = getEditMode()
    if (edit && edit.expiresAt > Date.now()) {
      config.headers.set('X-Org-Override-Reason', edit.reason)
    }
  }
  return config
})

const ORG_OVERRIDE_KEY = 'superAdminAsOrg'
export interface OrgOverride { id: string; name: string }
export function getOrgOverride(): OrgOverride | null {
  try {
    const raw = localStorage.getItem(ORG_OVERRIDE_KEY)
    return raw ? JSON.parse(raw) as OrgOverride : null
  } catch { return null }
}
export function setOrgOverride(value: OrgOverride | null, opts?: { redirectTo?: string }) {
  if (value) localStorage.setItem(ORG_OVERRIDE_KEY, JSON.stringify(value))
  else { localStorage.removeItem(ORG_OVERRIDE_KEY); localStorage.removeItem(EDIT_MODE_KEY) }
  // Hard navigation чтобы (а) снести TanStack Query кэш, (б) гарантированно
  // выйти из текущего layout'а в нужный (override → tenant /dashboard,
  // выход → /super-admin/organizations). Без redirectTo — просто reload
  // на ту же страницу (старое поведение, для совместимости).
  if (typeof window !== 'undefined') {
    if (opts?.redirectTo) window.location.assign(opts.redirectTo)
    else window.location.reload()
  }
}

const EDIT_MODE_KEY = 'superAdminEditMode'
export interface EditMode { reason: string; expiresAt: number }
export function getEditMode(): EditMode | null {
  try {
    const raw = localStorage.getItem(EDIT_MODE_KEY)
    if (!raw) return null
    const v = JSON.parse(raw) as EditMode
    if (v.expiresAt < Date.now()) { localStorage.removeItem(EDIT_MODE_KEY); return null }
    return v
  } catch { return null }
}
/** Включает edit-mode на 30 минут (по таймеру localStorage). После
 * истечения axios перестаёт слать reason, мутации снова блокируются. */
export function enableEditMode(reason: string) {
  const v: EditMode = { reason: reason.trim(), expiresAt: Date.now() + 30 * 60 * 1000 }
  localStorage.setItem(EDIT_MODE_KEY, JSON.stringify(v))
  if (typeof window !== 'undefined') window.location.reload()
}
export function disableEditMode() {
  localStorage.removeItem(EDIT_MODE_KEY)
  if (typeof window !== 'undefined') window.location.reload()
}

let refreshing: Promise<string | null> | null = null

api.interceptors.response.use(
  (res) => res,
  async (error: AxiosError) => {
    const original = error.config as InternalAxiosRequestConfig & { __retried?: boolean }
    if (error.response?.status === 401 && !original.__retried) {
      original.__retried = true
      refreshing ??= refreshTokens().finally(() => { refreshing = null })
      const newToken = await refreshing
      if (newToken) {
        original.headers.set('Authorization', `Bearer ${newToken}`)
        return api(original)
      }
      clearTokens()
      // Redirect to login so user isn't stuck on a protected page with stale tokens.
      if (typeof window !== 'undefined' && !window.location.pathname.startsWith('/login')) {
        window.location.href = '/login'
      }
    }
    return Promise.reject(error)
  },
)
