/**
 * Knowledge Base Service
 * Handles all knowledge-related API operations using TanStack Query patterns
 */

import { invalidateETagCache } from "../../projects/shared/apiWithEtag";
import { callKnowledgeAPI, uploadWithEnhancedErrors } from "./apiWithEnhancedErrors";
import type {
  ChunksResponse,
  CodeExamplesResponse,
  CrawlRequest,
  CrawlStartResponse,
  KnowledgeItem,
  KnowledgeItemsFilter,
  KnowledgeItemsResponse,
  KnowledgeSource,
  RefreshResponse,
  SearchOptions,
  SearchResultsResponse,
  UploadMetadata,
} from "../types";

export const knowledgeService = {
  /**
   * Get lightweight summaries of knowledge items
   * Use this for card displays and frequent updates
   */
  async getKnowledgeSummaries(filter?: KnowledgeItemsFilter): Promise<KnowledgeItemsResponse> {
    const params = new URLSearchParams();

    if (filter?.page) params.append("page", filter.page.toString());
    if (filter?.per_page) params.append("per_page", filter.per_page.toString());
    if (filter?.knowledge_type) params.append("knowledge_type", filter.knowledge_type);
    if (filter?.search) params.append("search", filter.search);
    if (filter?.tags?.length) {
      for (const tag of filter.tags) {
        params.append("tags", tag);
      }
    }

    const queryString = params.toString();
    const endpoint = `/api/knowledge-items/summary${queryString ? `?${queryString}` : ""}`;

    return callKnowledgeAPI<KnowledgeItemsResponse>(endpoint);
  },

  /**
   * Get a specific knowledge item
   */
  async getKnowledgeItem(sourceId: string): Promise<KnowledgeItem> {
    return callKnowledgeAPI<KnowledgeItem>(`/api/knowledge-items/${sourceId}`);
  },

  /**
   * Delete a knowledge item
   */
  async deleteKnowledgeItem(sourceId: string): Promise<{ success: boolean; message: string }> {
    const response = await callKnowledgeAPI<{ success: boolean; message: string }>(`/api/knowledge-items/${sourceId}`, {
      method: "DELETE",
    });

    // Invalidate cache after deletion
    invalidateETagCache("/api/knowledge-items");
    invalidateETagCache("/api/knowledge-items/summary");
    invalidateETagCache(`/api/knowledge-items/${sourceId}`);

    return response;
  },

  /**
   * Update a knowledge item
   */
  async updateKnowledgeItem(sourceId: string, updates: Partial<KnowledgeItem>): Promise<KnowledgeItem> {
    const response = await callKnowledgeAPI<KnowledgeItem>(`/api/knowledge-items/${sourceId}`, {
      method: "PUT",
      body: JSON.stringify(updates),
    });

    // Invalidate both list and specific item cache
    invalidateETagCache("/api/knowledge-items");
    invalidateETagCache("/api/knowledge-items/summary");
    invalidateETagCache(`/api/knowledge-items/${sourceId}`);

    return response;
  },

  /**
   * Start crawling a URL
   */
  async crawlUrl(request: CrawlRequest): Promise<CrawlStartResponse> {
    const response = await callKnowledgeAPI<CrawlStartResponse>("/api/knowledge-items/crawl", {
      method: "POST",
      body: JSON.stringify(request),
    });

    // Invalidate list cache as new item will be added
    invalidateETagCache("/api/knowledge-items");
    invalidateETagCache("/api/knowledge-items/summary");

    return response;
  },

  /**
   * Refresh an existing knowledge item
   */
  async refreshKnowledgeItem(sourceId: string): Promise<RefreshResponse> {
    const response = await callKnowledgeAPI<RefreshResponse>(`/api/knowledge-items/${sourceId}/refresh`, {
      method: "POST",
    });

    // Invalidate caches
    invalidateETagCache("/api/knowledge-items");
    invalidateETagCache("/api/knowledge-items/summary");
    invalidateETagCache(`/api/knowledge-items/${sourceId}`);

    return response;
  },

  /**
   * Upload a document
   */
  async uploadDocument(
    file: File,
    metadata: UploadMetadata,
  ): Promise<{ success: boolean; progressId: string; message: string; filename: string }> {
    const formData = new FormData();
    formData.append("file", file);

    if (metadata.knowledge_type) {
      formData.append("knowledge_type", metadata.knowledge_type);
    }
    if (metadata.tags?.length) {
      formData.append("tags", JSON.stringify(metadata.tags));
    }

    // Use enhanced upload wrapper with OpenAI error handling
    const result = await uploadWithEnhancedErrors("/documents/upload", formData, 30000);

    // Invalidate list cache
    invalidateETagCache("/api/knowledge-items");
    invalidateETagCache("/api/knowledge-items/summary");

    return result;
  },

  /**
   * Stop a running crawl
   */
  async stopCrawl(progressId: string): Promise<{ success: boolean; message: string }> {
    return callKnowledgeAPI<{ success: boolean; message: string }>(`/api/knowledge-items/stop/${progressId}`, {
      method: "POST",
    });
  },

  /**
   * Get document chunks for a knowledge item with pagination
   */
  async getKnowledgeItemChunks(
    sourceId: string,
    options?: {
      domainFilter?: string;
      limit?: number;
      offset?: number;
    },
  ): Promise<ChunksResponse> {
    const params = new URLSearchParams();
    if (options?.domainFilter) {
      params.append("domain_filter", options.domainFilter);
    }
    if (options?.limit !== undefined) {
      params.append("limit", options.limit.toString());
    }
    if (options?.offset !== undefined) {
      params.append("offset", options.offset.toString());
    }

    const queryString = params.toString();
    const endpoint = `/api/knowledge-items/${sourceId}/chunks${queryString ? `?${queryString}` : ""}`;

    return callKnowledgeAPI<ChunksResponse>(endpoint);
  },

  /**
   * Get code examples for a knowledge item with pagination
   */
  async getCodeExamples(
    sourceId: string,
    options?: {
      limit?: number;
      offset?: number;
    },
  ): Promise<CodeExamplesResponse> {
    const params = new URLSearchParams();
    if (options?.limit !== undefined) {
      params.append("limit", options.limit.toString());
    }
    if (options?.offset !== undefined) {
      params.append("offset", options.offset.toString());
    }

    const queryString = params.toString();
    const endpoint = `/api/knowledge-items/${sourceId}/code-examples${queryString ? `?${queryString}` : ""}`;

    return callKnowledgeAPI<CodeExamplesResponse>(endpoint);
  },

  /**
   * Search the knowledge base
   */
  async searchKnowledgeBase(options: SearchOptions): Promise<SearchResultsResponse> {
    return callKnowledgeAPI("/api/knowledge-items/search", {
      method: "POST",
      body: JSON.stringify(options),
    });
  },

  /**
   * Get available knowledge sources
   */
  async getKnowledgeSources(): Promise<KnowledgeSource[]> {
    return callKnowledgeAPI<KnowledgeSource[]>("/api/knowledge-items/sources");
  },
};
