// Web Browsing Library
// Fetches latest bursaries, university info, career information, etc.
// Uses fetch + cheerio for HTML parsing

import * as cheerio from 'cheerio'
import ZAI from 'z-ai-web-dev-sdk'

/**
 * General web search using z-ai-web-dev-sdk
 */
export async function searchWeb(query: string, numResults = 10) {
  try {
    const zai = await ZAI.create()
    const results = await zai.functions.invoke('web_search', {
      query,
      num: numResults,
    })
    return results
  } catch (error) {
    console.error('Web search failed:', error instanceof Error ? error.message : error)
    return []
  }
}

/**
 * Fetch and parse HTML from a URL
 */
async function fetchPage(url: string): Promise<string | null> {
  try {
    const response = await fetch(url, {
      headers: {
        'User-Agent':
          'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
      },
      signal: AbortSignal.timeout(15000),
    })

    if (!response.ok) return null
    return await response.text()
  } catch (error) {
    console.error(`Failed to fetch ${url}:`, error instanceof Error ? error.message : error)
    return null
  }
}

/**
 * Extract text content from HTML, removing scripts and styles
 */
function extractText(html: string): string {
  const $ = cheerio.load(html)
  $('script, style, nav, footer, header, iframe, noscript').remove()
  return $('body').text().replace(/\s+/g, ' ').trim()
}

/**
 * Fetch latest South African bursary listings
 * Uses web search to find current bursary opportunities
 */
export async function fetchBursaries() {
  try {
    const searchResults = await searchWeb(
      'South Africa bursaries 2025 2026 applications open scholarships',
      15
    )

    if (!searchResults || searchResults.length === 0) {
      return []
    }

    const bursaries = await Promise.allSettled(
      searchResults.slice(0, 10).map(async (result) => {
        const html = await fetchPage(result.url)
        if (!html) return null

        const $ = cheerio.load(html)
        const text = extractText(html)

        // Try to extract structured bursary info
        return {
          title: $('h1').first().text().trim() || result.name,
          description: text.slice(0, 500),
          sourceUrl: result.url,
          sourceName: result.host_name,
          snippet: result.snippet,
          fetchedAt: new Date().toISOString(),
        }
      })
    )

    return bursaries
      .filter(
        (r): r is PromiseFulfilledResult<NonNullable<typeof r.value>> =>
          r.status === 'fulfilled' && r.value !== null
      )
      .map((r) => r.value)
  } catch (error) {
    console.error('Failed to fetch bursaries:', error instanceof Error ? error.message : error)
    return []
  }
}

/**
 * Fetch university information from the web
 * @param university - Optional specific university name to search for
 */
export async function fetchUniversityInfo(university?: string) {
  const query = university
    ? `${university} South Africa courses admission requirements 2025`
    : 'South African universities courses admission requirements 2025'

  try {
    const searchResults = await searchWeb(query, 10)

    if (!searchResults || searchResults.length === 0) {
      return []
    }

    const universities = await Promise.allSettled(
      searchResults.slice(0, 8).map(async (result) => {
        const html = await fetchPage(result.url)
        if (!html) return null

        const text = extractText(html)

        return {
          name: university || result.name,
          description: text.slice(0, 600),
          sourceUrl: result.url,
          sourceName: result.host_name,
          snippet: result.snippet,
          fetchedAt: new Date().toISOString(),
        }
      })
    )

    return universities
      .filter(
        (r): r is PromiseFulfilledResult<NonNullable<typeof r.value>> =>
          r.status === 'fulfilled' && r.value !== null
      )
      .map((r) => r.value)
  } catch (error) {
    console.error('Failed to fetch university info:', error instanceof Error ? error.message : error)
    return []
  }
}

/**
 * Fetch career information from the web
 * @param career - Optional specific career to search for
 */
export async function fetchCareerInfo(career?: string) {
  const query = career
    ? `${career} career South Africa salary requirements qualifications`
    : 'top careers in demand South Africa 2025 salary information'

  try {
    const searchResults = await searchWeb(query, 10)

    if (!searchResults || searchResults.length === 0) {
      return []
    }

    const careers = await Promise.allSettled(
      searchResults.slice(0, 8).map(async (result) => {
        const html = await fetchPage(result.url)
        if (!html) {
          // Return search result data even if page can't be fetched
          return {
            title: result.name,
            snippet: result.snippet,
            sourceUrl: result.url,
            sourceName: result.host_name,
            fetchedAt: new Date().toISOString(),
          }
        }

        const text = extractText(html)

        return {
          title: result.name,
          description: text.slice(0, 600),
          snippet: result.snippet,
          sourceUrl: result.url,
          sourceName: result.host_name,
          fetchedAt: new Date().toISOString(),
        }
      })
    )

    return careers
      .filter(
        (r): r is PromiseFulfilledResult<NonNullable<typeof r.value>> =>
          r.status === 'fulfilled' && r.value !== null
      )
      .map((r) => r.value)
  } catch (error) {
    console.error('Failed to fetch career info:', error instanceof Error ? error.message : error)
    return []
  }
}

/**
 * Fetch content from a specific URL and return structured data
 */
export async function fetchUrlContent(url: string) {
  const html = await fetchPage(url)
  if (!html) return null

  const $ = cheerio.load(html)

  return {
    title: $('title').text().trim(),
    metaDescription: $('meta[name="description"]').attr('content') || '',
    headings: $('h1, h2, h3')
      .map((_, el) => $(el).text().trim())
      .get()
      .filter(Boolean),
    text: extractText(html),
    links: $('a[href]')
      .map((_, el) => ({
        text: $(el).text().trim(),
        href: $(el).attr('href'),
      }))
      .get()
      .filter((l) => l.text && l.href),
  }
}
