/**
 * AI 어시스턴트 전용 API 클라이언트
 * - VEXPLOR와 같은 서비스/같은 포트: /api/ai/v1 로 호출 (Next → backend-node → AI 서비스 프록시)
 * - 인증 토큰은 sessionStorage 'ai-assistant-auth' 사용 (VEXPLOR 인증과 분리)
 */
import axios, { AxiosError } from "axios";
import type { AiAssistantAuthState } from "./types";

const STORAGE_KEY = "ai-assistant-auth";

/** 같은 오리진 기준 AI API prefix (backend-node가 /api/ai/v1 을 AI 서비스로 프록시) */
function getBaseUrl(): string {
  if (typeof window === "undefined") return "";
  return "/api/ai/v1";
}

export function getAiAssistantAuth(): AiAssistantAuthState | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = sessionStorage.getItem(STORAGE_KEY);
    return raw ? (JSON.parse(raw) as AiAssistantAuthState) : null;
  } catch {
    return null;
  }
}

export function setAiAssistantAuth(state: AiAssistantAuthState | null): void {
  if (typeof window === "undefined") return;
  if (state) sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state));
  else sessionStorage.removeItem(STORAGE_KEY);
}

export function getAiAssistantAccessToken(): string | null {
  return getAiAssistantAuth()?.accessToken ?? null;
}

let refreshing = false;
const queue: Array<{ resolve: (t: string) => void; reject: (e: unknown) => void }> = [];

function processQueue(error: unknown, token: string | null) {
  queue.forEach((p) => (error ? p.reject(error) : p.resolve(token!)));
  queue.length = 0;
}

const client = axios.create({
  baseURL: "",
  headers: { "Content-Type": "application/json" },
});

client.interceptors.request.use((config) => {
  const base = getBaseUrl();
  if (base) config.baseURL = base;
  const token = getAiAssistantAccessToken();
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

client.interceptors.response.use(
  (res) => res,
  async (err: AxiosError) => {
    const original = err.config as typeof err.config & { _retry?: boolean };
    const isAuth = original?.url?.includes("/auth/");
    if (isAuth || err.response?.status !== 401 || original?._retry) {
      return Promise.reject(err);
    }

    if (refreshing) {
      return new Promise<string>((resolve, reject) => {
        queue.push({ resolve, reject });
      })
        .then((token) => {
          if (original.headers) original.headers.Authorization = `Bearer ${token}`;
          return client(original);
        })
        .catch((e) => Promise.reject(e));
    }

    original._retry = true;
    refreshing = true;
    const auth = getAiAssistantAuth();
    try {
      if (!auth?.refreshToken) throw new Error("No refresh token");
      const base = getBaseUrl();
      const { data } = await axios.post<{ data: { accessToken: string } }>(
        `${base}/auth/refresh`,
        { refreshToken: auth.refreshToken },
        { headers: { "Content-Type": "application/json" } },
      );
      const newToken = data?.data?.accessToken;
      if (!newToken) throw new Error("No access token");
      const newState: AiAssistantAuthState = {
        ...auth,
        accessToken: newToken,
      };
      setAiAssistantAuth(newState);
      processQueue(null, newToken);
      if (original.headers) original.headers.Authorization = `Bearer ${newToken}`;
      return client(original);
    } catch (e) {
      processQueue(e, null);
      setAiAssistantAuth(null);
      return Promise.reject(err);
    } finally {
      refreshing = false;
    }
  },
);

/** AI 어시스턴트 로그인 (이메일/비밀번호) */
export async function loginAiAssistant(
  email: string,
  password: string,
): Promise<AiAssistantAuthState> {
  const base = getBaseUrl();
  const { data } = await axios.post<{
    data: { user: AiAssistantAuthState["user"]; accessToken: string; refreshToken: string };
  }>(`${base}/auth/login`, { email, password }, { headers: { "Content-Type": "application/json" }, withCredentials: true });
  const state: AiAssistantAuthState = {
    user: data.data.user,
    accessToken: data.data.accessToken,
    refreshToken: data.data.refreshToken,
  };
  setAiAssistantAuth(state);
  return state;
}

export default client;
