import { getToken, clearAuth } from './adminAuth';

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000';

export class ApiError extends Error {
  status: number;

  constructor(message: string, status: number) {
    super(message);
    this.status = status;
  }
}

function parseFilenameFromContentDisposition(contentDisposition: string | null): string | null {
  if (!contentDisposition) return null;

  // Prefer RFC 5987 filename*=UTF-8''...
  const filenameStarMatch = contentDisposition.match(/filename\*=(?:UTF-8''|utf-8'')([^;]+)/);
  if (filenameStarMatch?.[1]) {
    try {
      return decodeURIComponent(filenameStarMatch[1].trim().replace(/^"|"$/g, ''));
    } catch {
      return filenameStarMatch[1].trim().replace(/^"|"$/g, '');
    }
  }

  const filenameMatch = contentDisposition.match(/filename=([^;]+)/);
  if (filenameMatch?.[1]) {
    return filenameMatch[1].trim().replace(/^"|"$/g, '');
  }

  return null;
}

async function request<T>(path: string, init?: RequestInit): Promise<T> {
  const token = getToken();

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
  };

  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  const res = await fetch(`${API_BASE_URL}${path}`, {
    ...init,
    headers: {
      ...headers,
      ...(init?.headers || {}),
    },
    credentials: 'include',
  });

  if (res.status === 401) {
    clearAuth();
  }

  const data = (await res.json().catch(() => ({}))) as any;

  if (!res.ok) {
    throw new ApiError(data?.message || `请求失败: ${res.status}`, res.status);
  }

  return data as T;
}

async function requestDownload(path: string, init?: RequestInit): Promise<{ blob: Blob; filename: string }>
{
  const token = getToken();

  const headers: Record<string, string> = {
    ...(init?.headers as any),
  };

  // Do NOT force Content-Type for downloads (GET binary)
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }

  const res = await fetch(`${API_BASE_URL}${path}`, {
    ...init,
    headers,
    credentials: 'include',
  });

  if (res.status === 401) {
    clearAuth();
  }

  if (!res.ok) {
    const text = await res.text().catch(() => '');
    // Try to extract message from JSON-ish body
    let message = `请求失败: ${res.status}`;
    try {
      const maybeJson = JSON.parse(text || '{}');
      message = maybeJson?.message || message;
    } catch {
      // ignore
    }
    throw new ApiError(message, res.status);
  }

  const filename =
    parseFilenameFromContentDisposition(res.headers.get('content-disposition')) || 'logs.tar.gz';
  const blob = await res.blob();
  return { blob, filename };
}

export const api = {
  adminLogin: (identifier: string, password: string) =>
    request<any>('/admin/auth/login', {
      method: 'POST',
      body: JSON.stringify({ identifier, password }),
    }),

  listUsers: (limit = 100, offset = 0) =>
    request<any>(`/admin/users?limit=${encodeURIComponent(limit)}&offset=${encodeURIComponent(offset)}`),

  resetUserPassword: (userId: string, newPassword: string) =>
    request<any>(`/admin/users/${encodeURIComponent(userId)}/reset-password`, {
      method: 'POST',
      body: JSON.stringify({ new_password: newPassword }),
    }),

  getRuntimeLogs: (lines = 200) =>
    request<any>(`/admin/logs/runtime?lines=${encodeURIComponent(lines)}`),

  downloadLogsArchive: () => requestDownload('/admin/logs/archive'),
};
