import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { apiClient } from '@/api/client'

/**
 * Interface for scan results
 */
interface ScanResults {
  site_type: string
  counts: {
    posts: number
    pages: number
    products: number
    categories: number
  }
  estimates: {
    time_minutes: number
    cost_usd: number
  }
  index_stats: {
    total_indexed: number
    by_type: Record<string, number>
  }
  content_preview: {
    posts: Array<{ id: number; title: string; url: string }>
    pages: Array<{ id: number; title: string; url: string }>
    products: Array<{ id: number; title: string; url: string }>
  }
}

/**
 * Interface for indexing status
 */
interface IndexingStatus {
  job: {
    id: string
    status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'
    progress: number
    processed: number
    total: number
    errors: number
    started_at: string | null
  } | null
  queue_stats?: {
    pending: number
    processing: number
    completed: number
    failed: number
    skipped: number
    total: number
  } | null
  index_stats: {
    total_indexed: number
    by_type: Record<string, number>
  }
  last_full_index: string | null
  is_indexing: boolean
  paused?: boolean
}

type IndexMode = 'deep' | 'deep_incremental'

interface IndexingEstimate {
  index_mode: IndexMode
  content_types: string[]
  items_total: number
  items_changed: number
  chars_total: number
  estimated_chunks: number
  /** @deprecated Week 30 - Use estimated_boost_credits instead */
  estimated_indexing_credits: number
  // Week 30: Unified BoostCoin - decimal value representing fractional coins.
  estimated_boost_credits: number
  by_type: Record<
    string,
    { items_total: number; items_changed: number; chars_total: number; chunks_total: number }
  >
}

// Week 30: Credits status now uses unified BoostCoin with decimal values
interface IndexingCreditsStatus {
  site_id: string
  site_status?: 'active' | 'blocked' | 'disabled'
  allowed: boolean
  /** @deprecated Week 30 - Use boost_credits instead. This now mirrors boost_credits for compatibility. */
  indexing_credits: { total: number; used: number; remaining: number }
  // Week 30: Unified BoostCoin wallet - values are decimal numbers
  boost_credits: { total: number; used: number; remaining: number }
}

interface IndexQueueStats {
  pending: number
  processing: number
  completed: number
  failed: number
  skipped: number
  total: number
}

interface IndexQueueItem {
  id: number
  content_id: number
  content_type: string
  priority: number
  status: 'pending' | 'processing' | 'completed' | 'failed' | 'skipped'
  extraction_level: number
  attempts: number
  max_attempts: number
  content_size: number
  last_error?: string | null
  memory_peak?: number | null
  processing_time?: number | null
  created_at?: string | null
  started_at?: string | null
  completed_at?: string | null
}

interface IndexQueueResponse {
  page: number
  per_page: number
  status: string | null
  total: number
  items: IndexQueueItem[]
  queue_stats: IndexQueueStats
}

/**
 * Hook to scan the site for content
 */
export function useScanSite() {
  return useQuery<{ success: boolean; data: ScanResults }>({
    queryKey: ['knowledge-base', 'scan'],
    queryFn: () => apiClient.get('index/scan'),
    staleTime: 5 * 60 * 1000, // 5 minutes
  })
}

/**
 * Week 24.5: Estimate indexing work (chunks/credits) for selected content + mode.
 */
export function useIndexingEstimate(indexMode: IndexMode, contentTypes: string[]) {
  const sorted = [...contentTypes].sort()
  return useQuery<{ success: boolean; data: IndexingEstimate }>({
    queryKey: ['knowledge-base', 'estimate', indexMode, sorted.join(',')],
    queryFn: () =>
      apiClient.get(
        `index/estimate?index_mode=${encodeURIComponent(indexMode)}&` +
          sorted.map((t) => `content_types[]=${encodeURIComponent(t)}`).join('&'),
      ),
    staleTime: 30 * 1000,
    enabled: contentTypes.length > 0,
  })
}

/**
 * Week 27: Indexing credits status (backend wallet).
 */
export function useIndexingCreditsStatus() {
  return useQuery<{ success: boolean; data: IndexingCreditsStatus }>({
    queryKey: ['knowledge-base', 'indexing-credits', 'status'],
    queryFn: () => apiClient.get('indexing-credits/status'),
    staleTime: 10 * 1000,
  })
}

/**
 * Hook to get indexing status
 */
export function useIndexingStatus() {
  return useQuery<{ success: boolean; data: IndexingStatus }>({
    queryKey: ['knowledge-base', 'status'],
    queryFn: () => apiClient.get('index/status'),
    refetchInterval: (query) => {
      const data = query.state.data?.data
      // Poll every 2 seconds while indexing is active
      if (data?.is_indexing) {
        return 2000
      }
      // Poll every 5 seconds if job exists but just started (might not be marked as indexing yet)
      if (data?.job && data.job.status === 'running') {
        return 2000
      }
      // Poll every 10 seconds even when not indexing to catch any new jobs
      return 10000
    },
    // Refetch immediately when window regains focus
    refetchOnWindowFocus: true,
  })
}

/**
 * Hook to start indexing
 */
export function useStartIndexing() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: (input: { contentTypes: string[]; indexMode: IndexMode }) =>
      apiClient.post('index/start', { content_types: input.contentTypes, index_mode: input.indexMode }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Hook to stop indexing
 */
export function useStopIndexing() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: () => apiClient.post('index/stop'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Pause indexing (does not cancel job).
 */
export function usePauseIndexing() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: () => apiClient.post('index/pause'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Resume indexing (continues the queue).
 */
export function useResumeIndexing() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: () => apiClient.post('index/resume'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Admin kick: process the next item (watchdog).
 */
export function useKickIndexing() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: () => apiClient.post('index/kick'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Retry all failed items in queue.
 */
export function useRetryAllFailed() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: () => apiClient.post('index/retry-all-failed'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Fetch queue items (paged).
 */
export function useIndexQueue(page = 1, perPage = 50, status?: string, enabled = true) {
  const key = ['knowledge-base', 'queue', page, perPage, status || 'all']
  const qs =
    `index/queue?page=${encodeURIComponent(String(page))}&per_page=${encodeURIComponent(String(perPage))}` +
    (status ? `&status=${encodeURIComponent(status)}` : '')
  return useQuery<{ success: boolean; data: IndexQueueResponse }>({
    queryKey: key,
    queryFn: () => apiClient.get(qs),
    enabled,
    staleTime: 2000,
  })
}

/**
 * Retry a specific queue row id.
 */
export function useRetryQueueItem() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: (id: number) => apiClient.post(`index/retry/${id}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Hook to clear the index
 */
export function useClearIndex() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: () => apiClient.delete('index/clear?confirm=true'),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Hook to search the knowledge base
 */
export function useSearchKnowledgeBase(query: string, enabled = true) {
  return useQuery({
    queryKey: ['knowledge-base', 'search', query],
    queryFn: () => apiClient.get(`index/search?q=${encodeURIComponent(query)}`),
    enabled: enabled && query.length > 2,
  })
}

// ====== Week 30: Indexed Content Visibility Management ======

// ── Taxonomy types ──

export interface TaxonomyTerm {
  id: number
  name: string
  slug: string
  count: number
}

export interface TaxonomyInfo {
  taxonomy: string
  label: string
  post_types: string[]
  hierarchical: boolean
  terms: TaxonomyTerm[]
}

// ── Indexed content types ──

export interface TaxonomyLabel {
  taxonomy: string
  tax_label: string
  term_id: number
  name: string
}

interface IndexedContentItem {
  id: number
  content_type: string
  content_id: number
  title: string
  url: string
  indexed_at: string
  updated_at: string
  is_enabled: boolean
  taxonomies?: TaxonomyLabel[]
  date_created?: string | null
  date_modified?: string | null
}

interface IndexedContentResponse {
  items: IndexedContentItem[]
  total: number
  page: number
  per_page: number
  pages: number
}

export interface IndexedContentFilters {
  page?: number
  perPage?: number
  contentType?: string
  search?: string
  enabled?: boolean | null
  taxonomy?: string        // "taxonomy_name:term_id"
  dateFrom?: string        // YYYY-MM-DD
  dateTo?: string          // YYYY-MM-DD
  sortBy?: string
  sortOrder?: 'ASC' | 'DESC'
}

/**
 * Fetch indexed content with pagination and rich filters.
 */
export function useIndexedContent(filters: IndexedContentFilters = {}, enabled = true) {
  const { page = 1, perPage = 50, contentType, search, enabled: enabledFilter, taxonomy, dateFrom, dateTo, sortBy, sortOrder } = filters;
  const params = new URLSearchParams()
  params.set('page', String(page))
  params.set('per_page', String(perPage))
  if (contentType) params.set('content_type', contentType)
  if (search) params.set('search', search)
  if (enabledFilter !== undefined && enabledFilter !== null) {
    params.set('enabled', enabledFilter ? '1' : '0')
  }
  if (taxonomy) params.set('taxonomy', taxonomy)
  if (dateFrom) params.set('date_from', dateFrom)
  if (dateTo) params.set('date_to', dateTo)
  if (sortBy) params.set('sort_by', sortBy)
  if (sortOrder) params.set('sort_order', sortOrder)

  const queryKey = ['indexed-content', page, perPage, contentType ?? '', search ?? '', String(enabledFilter ?? 'all'), taxonomy ?? '', dateFrom ?? '', dateTo ?? '', sortBy ?? '', sortOrder ?? '']

  return useQuery<{ success: boolean; data: IndexedContentResponse }>({
    queryKey,
    queryFn: () => apiClient.get(`index/indexed-content?${params.toString()}`),
    enabled,
    staleTime: 5000,
  })
}

/**
 * Toggle is_enabled for a single indexed entry.
 */
export function useToggleContentEnabled() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: (args: { id: number; enabled?: boolean }) =>
      apiClient.post(`index/indexed-content/${args.id}/toggle`, { enabled: args.enabled }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['indexed-content'] })
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

/**
 * Bulk toggle is_enabled for multiple entries.
 */
export function useBulkToggleContentEnabled() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: (args: { ids: number[]; enabled: boolean }) =>
      apiClient.post('index/indexed-content/bulk-toggle', { ids: args.ids, enabled: args.enabled }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['indexed-content'] })
      queryClient.invalidateQueries({ queryKey: ['knowledge-base'] })
    },
  })
}

// ── Site Content Browser (pre-indexing) ──

export interface SiteContentItem {
  id: number
  title: string
  url: string
  content_type: string
  date_created: string
  date_modified: string
  taxonomies: TaxonomyLabel[]
  is_excluded: boolean
  is_indexed: boolean
  index_enabled: boolean | null
}

interface SiteContentResponse {
  items: SiteContentItem[]
  total: number
  page: number
  per_page: number
  pages: number
}

export interface SiteContentFilters {
  page?: number
  perPage?: number
  contentType?: string
  search?: string
  taxonomy?: string
  dateFrom?: string
  dateTo?: string
  dateType?: 'created' | 'modified'
  sortBy?: 'title' | 'date' | 'modified'
  sortOrder?: 'ASC' | 'DESC'
  /** 'excluded' = only excluded items, 'included' = only non-excluded, undefined = all */
  excluded?: 'excluded' | 'included'
}

/**
 * Browse ALL WordPress content with rich filters (pre-indexing).
 */
export function useSiteContent(filters: SiteContentFilters = {}, enabled = true) {
  const { page = 1, perPage = 30, contentType, search, taxonomy, dateFrom, dateTo, dateType, sortBy, sortOrder, excluded } = filters
  const params = new URLSearchParams()
  params.set('page', String(page))
  params.set('per_page', String(perPage))
  if (contentType) params.set('content_type', contentType)
  if (search) params.set('search', search)
  if (taxonomy) params.set('taxonomy', taxonomy)
  if (dateFrom) params.set('date_from', dateFrom)
  if (dateTo) params.set('date_to', dateTo)
  if (dateType) params.set('date_type', dateType)
  if (sortBy) params.set('sort_by', sortBy)
  if (sortOrder) params.set('sort_order', sortOrder)
  if (excluded) params.set('excluded', excluded)

  const queryKey = ['site-content', page, perPage, contentType ?? '', search ?? '', taxonomy ?? '', dateFrom ?? '', dateTo ?? '', dateType ?? '', sortBy ?? '', sortOrder ?? '', excluded ?? '']

  return useQuery<{ success: boolean; data: SiteContentResponse }>({
    queryKey,
    queryFn: () => apiClient.get(`index/site-content?${params.toString()}`),
    enabled,
    staleTime: 10000,
  })
}

/**
 * Fetch all available taxonomies with their terms.
 */
export function useTaxonomies() {
  return useQuery<{ success: boolean; data: TaxonomyInfo[] }>({
    queryKey: ['taxonomies'],
    queryFn: () => apiClient.get('index/taxonomies'),
    staleTime: 60000,
  })
}

/**
 * Get the current exclusion list.
 */
export function useExcludedIds() {
  return useQuery<{ success: boolean; data: { excluded_ids: number[] } }>({
    queryKey: ['excluded-ids'],
    queryFn: () => apiClient.get('index/excluded-ids'),
    staleTime: 5000,
  })
}

/**
 * Modify the exclusion list.
 */
export function useSetExcludedIds() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: (args: { action: 'add' | 'remove' | 'set'; ids: number[] }) =>
      apiClient.post('index/excluded-ids', args),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['excluded-ids'] })
      queryClient.invalidateQueries({ queryKey: ['site-content'] })
    },
  })
}
