import type {
  CategoryListResponse,
  Pattern,
  PatternListResponse,
  PatternTutorial,
  QuestionDetail,
  QuestionListResponse,
  Stats,
  SubmissionRequest,
  SubmissionResponse,
} from "@/types";

// Server-side uses internal Docker network, client-side uses public URL
const API_BASE_URL =
  typeof window === "undefined"
    ? process.env.API_URL || "http://localhost:8000"
    : process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";

export class ApiError extends Error {
  constructor(
    public status: number,
    public statusText: string,
    public detail?: string
  ) {
    super(detail || `API error: ${status} ${statusText}`);
    this.name = "ApiError";
  }
}

async function fetchApi<T>(
  endpoint: string,
  options?: RequestInit
): Promise<T> {
  const url = `${API_BASE_URL}${endpoint}`;
  const response = await fetch(url, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });

  if (!response.ok) {
    let detail: string | undefined;
    try {
      const errorBody = await response.json();
      detail = errorBody.detail;
    } catch {
      // Ignore JSON parse errors
    }
    throw new ApiError(response.status, response.statusText, detail);
  }

  return response.json();
}

export interface QuestionFilters {
  page?: number;
  limit?: number;
  difficulty?: string;
  category?: string;
  pattern?: string;
  search?: string;
}

export async function getQuestions(
  filters: QuestionFilters = {}
): Promise<QuestionListResponse> {
  const params = new URLSearchParams();

  if (filters.page) params.set("page", filters.page.toString());
  if (filters.limit) params.set("limit", filters.limit.toString());
  if (filters.difficulty) params.set("difficulty", filters.difficulty);
  if (filters.category) params.set("category", filters.category);
  if (filters.pattern) params.set("pattern", filters.pattern);
  if (filters.search) params.set("search", filters.search);

  const queryString = params.toString();
  const endpoint = queryString
    ? `/api/questions?${queryString}`
    : "/api/questions";

  return fetchApi<QuestionListResponse>(endpoint);
}

export async function getQuestion(slug: string): Promise<QuestionDetail> {
  return fetchApi<QuestionDetail>(`/api/questions/${slug}`);
}

export async function getCategories(): Promise<CategoryListResponse> {
  return fetchApi<CategoryListResponse>("/api/categories");
}

export async function getPatterns(): Promise<PatternListResponse> {
  return fetchApi<PatternListResponse>("/api/patterns");
}

export async function getPattern(slug: string): Promise<Pattern> {
  return fetchApi<Pattern>(`/api/patterns/${slug}`);
}

export async function getPatternTutorial(slug: string): Promise<PatternTutorial> {
  return fetchApi<PatternTutorial>(`/api/patterns/${slug}/tutorial`);
}

export async function getStats(): Promise<Stats> {
  return fetchApi<Stats>("/api/stats");
}

export async function submitSolution(
  slug: string,
  submission: SubmissionRequest
): Promise<SubmissionResponse> {
  return fetchApi<SubmissionResponse>(`/api/questions/${slug}/submit`, {
    method: "POST",
    body: JSON.stringify(submission),
  });
}
