const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5123';

export interface FileTreeNode {
  name: string;
  path: string;
  type: 'file' | 'folder';
  children?: FileTreeNode[];
}

export interface RepositoryInfo {
  name: string;
}

export interface FileContentResponse {
  path: string;
  content: string;
}

export interface CheckFileRequest {
  fileContent: string;
  fileName: string;
  checkType: 'language' | 'content';
}

export interface CheckFileResponse {
  result: string;
}

export type FlashcardDifficulty = 'Easy' | 'Medium';

export interface GenerateFlashcardsRequest {
  filePaths: string[];
  amount: number;
  difficulty: FlashcardDifficulty;
}

export interface FlashcardCard {
  id: number;
  libraryId: number;
  front: string;
  back: string;
  position: number;
  correctCount: number;
  incorrectCount: number;
  createdAt: string;
  lastReviewedAt?: string | null;
}

export interface FlashcardLibrarySummary {
  id: number;
  filePath: string;
  fileName: string;
  subject: string;
  difficulty: string;
  cardCount: number;
  createdAt: string;
  updatedAt: string;
}

export interface FlashcardLibraryDetails extends FlashcardLibrarySummary {
  cards: FlashcardCard[];
}

export interface GenerateFlashcardsResponse {
  libraries: FlashcardLibraryDetails[];
}

export interface FlashcardReviewSessionRequest {
  libraryIds: number[];
}

export interface FlashcardReviewSessionResponse {
  cards: FlashcardCard[];
}

export interface FlashcardReviewAnswerRequest {
  cardId: number;
  correct: boolean;
}

export type FlashcardRagStatus = 'Grey' | 'Red' | 'Amber' | 'Green';

export interface FlashcardRagLibrary {
  libraryId: number;
  filePath: string;
  fileName: string;
  subject: string;
  subSubject: string;
  cardCount: number;
  correctCount: number;
  incorrectCount: number;
  totalAnswers: number;
  performanceRate: number;
  lastReviewedAt?: string | null;
  ragStatus: FlashcardRagStatus;
}

export interface FlashcardRagSummary {
  greenCount: number;
  amberCount: number;
  redCount: number;
  greyCount: number;
  activeCount: number;
  greenPercentage: number;
  attentionPercentage: number;
}

export interface FlashcardRagSubSubjectGroup {
  subSubject: string;
  summary: FlashcardRagSummary;
  libraries: FlashcardRagLibrary[];
}

export interface FlashcardRagSubjectGroup {
  subject: string;
  summary: FlashcardRagSummary;
  subSubjects: FlashcardRagSubSubjectGroup[];
}

export interface FlashcardRagDashboardResponse {
  generatedAt: string;
  subjects: FlashcardRagSubjectGroup[];
}

async function throwIfNotOk(response: Response, fallback: string) {
  if (response.ok) {
    return;
  }

  let apiMessage = '';
  try {
    const body = await response.json();
    if (typeof body?.error === 'string' && body.error.length > 0) {
      apiMessage = body.error;
    }
  } catch {
    // Ignore parse failures and throw fallback below.
  }

  throw new Error(apiMessage || fallback);
}

export const MindforgeApiService = {
  async checkFile(data: CheckFileRequest): Promise<CheckFileResponse> {
    const response = await fetch(`${BASE_URL}/api/v1/file/check`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    await throwIfNotOk(response, `Erro ao validar arquivo: ${response.statusText}`);
    return response.json();
  },

  async generateFlashcards(data: GenerateFlashcardsRequest): Promise<GenerateFlashcardsResponse> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/generate`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    await throwIfNotOk(response, `Erro ao gerar flashcards: ${response.statusText}`);
    return response.json();
  },

  async getFlashcardLibraries(): Promise<FlashcardLibrarySummary[]> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/libraries`);
    await throwIfNotOk(response, `Erro ao buscar bibliotecas de flashcards: ${response.statusText}`);
    return response.json();
  },

  async getFlashcardLibrary(id: number): Promise<FlashcardLibraryDetails> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/libraries/${id}`);
    await throwIfNotOk(response, `Erro ao buscar biblioteca ${id}: ${response.statusText}`);
    return response.json();
  },

  async createFlashcardReviewSession(data: FlashcardReviewSessionRequest): Promise<FlashcardReviewSessionResponse> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/review-session`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    await throwIfNotOk(response, `Erro ao iniciar revisão: ${response.statusText}`);
    return response.json();
  },

  async recordFlashcardReviewAnswer(data: FlashcardReviewAnswerRequest): Promise<void> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/review-answer`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    await throwIfNotOk(response, `Erro ao registrar resposta da revisão: ${response.statusText}`);
  },

  async getFlashcardRagStatus(): Promise<FlashcardRagDashboardResponse> {
    const response = await fetch(`${BASE_URL}/api/v1/flashcard/rag-status`);
    await throwIfNotOk(response, `Erro ao buscar status RAG de revisão: ${response.statusText}`);
    return response.json();
  },

  async getRepositoryInfo(): Promise<RepositoryInfo> {
    const response = await fetch(`${BASE_URL}/api/v1/repository/info`);
    await throwIfNotOk(response, `Erro ao buscar info do repositório: ${response.statusText}`);
    return response.json();
  },

  async getRepositoryTree(): Promise<FileTreeNode[]> {
    const response = await fetch(`${BASE_URL}/api/v1/repository/tree`);
    await throwIfNotOk(response, `Erro ao buscar árvore do repositório: ${response.statusText}`);
    return response.json();
  },

  async getFileContent(path: string): Promise<FileContentResponse> {
    const response = await fetch(`${BASE_URL}/api/v1/repository/file?path=${encodeURIComponent(path)}`);
    await throwIfNotOk(response, `Erro ao buscar arquivo ${path}: ${response.statusText}`);
    return response.json();
  },
};
