import { Router } from 'express'
import { basename, join } from 'node:path'
import { config } from '../config.js'
import { servicesService } from '../services/services_service.js'
import { knowledgeService } from '../services/knowledge_service.js'
import { aiService } from '../services/ai_service.js'
import { downloadService } from '../services/download_service.js'
import { catalogService } from '../services/catalog_service.js'
import { zimService, type ZimArchive } from '../services/zim_service.js'
import type { ResourceType } from '../data/catalog.js'
import type { ChatMessage } from '../types.js'

const router = Router()

/** Atveria atsisiųsto wiki ištekliaus ZIM archyvą pagal resourceId. */
async function openZim(resourceId: string): Promise<ZimArchive | null> {
  const r = await catalogService.get(resourceId)
  if (!r || r.type !== 'wiki') return null
  try {
    return zimService.open(join(config.storagePath, 'wiki', basename(r.filename)))
  } catch {
    return null
  }
}

/** Būklės patikra / health check. */
router.get('/health', (_req, res) => {
  res.json({
    status: 'ok',
    service: 'tcp-arka',
    version: '0.2.0',
    mode: 'local-only',
    time: new Date().toISOString(),
    tcpUrl: config.tcpUrl,
  })
})

/** Bendra mazgo būklė: moduliai, lygmenys, pasiruošimas. */
router.get('/system/status', async (_req, res) => {
  res.json(await servicesService.getStatus())
})

router.get('/modules', (_req, res) => {
  res.json({ modules: servicesService.listModules() })
})

router.get('/modules/:id', (req, res) => {
  const mod = servicesService.getModule(req.params.id)
  if (!mod) return res.status(404).json({ error: 'Modulis nerastas / module not found' })
  res.json(mod)
})

/** Žinių bazė: sąrašas, paieška, įrašas. */
router.get('/knowledge', (req, res) => {
  const q = typeof req.query.q === 'string' ? req.query.q : ''
  const category = typeof req.query.category === 'string' ? req.query.category : undefined
  if (q) {
    return res.json({ query: q, results: knowledgeService.search(q) })
  }
  res.json({ entries: knowledgeService.list(category) })
})

router.get('/knowledge/:id', (req, res) => {
  const entry = knowledgeService.get(req.params.id)
  if (!entry) return res.status(404).json({ error: 'Įrašas nerastas / entry not found' })
  res.json(entry)
})

/** Lokalaus AI asistento pokalbis (RAG). */
router.post('/ai/chat', async (req, res) => {
  const messages = req.body?.messages as ChatMessage[] | undefined
  if (!Array.isArray(messages) || messages.length === 0) {
    return res.status(400).json({ error: 'Trūksta „messages" lauko / missing messages' })
  }
  try {
    const reply = await aiService.chat(messages)
    res.json(reply)
  } catch (err) {
    res.status(500).json({ error: 'AI klaida / AI error', detail: String(err) })
  }
})

/**
 * Atsisiunčiamo turinio katalogas su realia būsena (wiki ZIM, žemėlapiai).
 * `?type=wiki|map` filtruoja.
 */
router.get('/catalog', async (req, res) => {
  const type =
    req.query.type === 'wiki' || req.query.type === 'map'
      ? (req.query.type as ResourceType)
      : undefined
  res.json({ items: await downloadService.catalog(type) })
})

/** Pridėti savo (custom) URL į katalogą. */
router.post('/catalog', async (req, res) => {
  const { type, name, description, url, sizeBytes } = req.body ?? {}
  try {
    const resource = await catalogService.add({ type, name, description, url, sizeBytes })
    res.status(201).json(resource)
  } catch (err) {
    res.status(400).json({ error: err instanceof Error ? err.message : String(err) })
  }
})

/** Pašalinti naudotojo pridėtą išteklių. */
router.delete('/catalog/:id', async (req, res) => {
  const removed = await catalogService.remove(req.params.id)
  if (!removed) {
    return res
      .status(404)
      .json({ error: 'Nerasta arba nepašalinamas / not found or not removable' })
  }
  res.json({ removed })
})

/** Visi atsisiuntimai (aktyvūs ir užbaigti). */
router.get('/downloads', (_req, res) => {
  res.json({ downloads: downloadService.list() })
})

/** Pradėti ištekliaus atsisiuntimą. */
router.post('/downloads', async (req, res) => {
  const resourceId = req.body?.resourceId
  if (typeof resourceId !== 'string') {
    return res.status(400).json({ error: 'Trūksta „resourceId" / missing resourceId' })
  }
  try {
    const task = await downloadService.start(resourceId)
    res.status(202).json(task)
  } catch (err) {
    res.status(404).json({ error: err instanceof Error ? err.message : String(err) })
  }
})

/**
 * Atsisiųsto failo atidavimas lokaliai peržiūrai. Palaiko HTTP Range
 * (būtina PMTiles žemėlapiams). `res.sendFile` (per `send`) Range tvarko pats.
 */
router.get('/files/:type/:filename', (req, res) => {
  const { type } = req.params
  if (type !== 'wiki' && type !== 'map') {
    return res.status(400).json({ error: 'Netinkamas tipas / invalid type' })
  }
  // basename pašalina bet kokį kelią → apsauga nuo path traversal.
  const filename = basename(req.params.filename)
  const filePath = join(config.storagePath, type, filename)
  res.sendFile(filePath, (err) => {
    if (err && !res.headersSent) {
      res.status(404).json({ error: 'Failas nerastas / file not found' })
    }
  })
})

/** ZIM (wiki) archyvo informacija: pavadinimas, straipsnių sk., pagrindinis kelias. */
router.get('/zim/:id/info', async (req, res) => {
  const zim = await openZim(req.params.id)
  if (!zim) return res.status(404).json({ error: 'ZIM nerastas / not found' })
  const main = zim.main()
  res.json({ articleCount: zim.articleCount, mainPath: main.url, mainTitle: main.title })
})

/** Paieška ZIM pagal straipsnio pavadinimą (greita). */
router.get('/zim/:id/search', async (req, res) => {
  const zim = await openZim(req.params.id)
  if (!zim) return res.status(404).json({ error: 'ZIM nerastas / not found' })
  const q = typeof req.query.q === 'string' ? req.query.q : ''
  res.json({ results: zim.searchTitles(q) })
})

/**
 * Pilno teksto paieška (straipsnio turinyje, ne tik pavadinime) su
 * ištraukomis. Pirmasis kreipinys sukuria indeksą (gali užtrukti dideliems
 * ZIM); vėliau jis įkeliamas iš disko.
 */
router.get('/zim/:id/fulltext', async (req, res) => {
  const zim = await openZim(req.params.id)
  if (!zim) return res.status(404).json({ error: 'ZIM nerastas / not found' })
  const q = typeof req.query.q === 'string' ? req.query.q : ''
  try {
    res.json(zim.fullTextSearch(q))
  } catch (err) {
    res.status(500).json({ error: err instanceof Error ? err.message : String(err) })
  }
})

/** Straipsnio / ištekliaus turinys iš ZIM (HTML, CSS, paveikslėliai). */
router.get('/zim/:id/content/*', async (req, res) => {
  const zim = await openZim(req.params.id)
  if (!zim) return res.status(404).json({ error: 'ZIM nerastas / not found' })
  const path = (req.params as Record<string, string>)[0] ?? ''
  try {
    const result = zim.content(path)
    if (!result) return res.status(404).send('Nerasta / not found')
    const isHtml = result.mime.startsWith('text/html')
    res.type(isHtml ? 'text/html; charset=utf-8' : result.mime)
    res.send(result.data)
  } catch (err) {
    res.status(500).json({ error: err instanceof Error ? err.message : String(err) })
  }
})

/** Vieno atsisiuntimo būsena (progresui sekti). */
router.get('/downloads/:id', (req, res) => {
  const task = downloadService.get(req.params.id)
  if (!task) return res.status(404).json({ error: 'Nerasta / not found' })
  res.json(task)
})

/** Atšaukti vykstantį atsisiuntimą. */
router.delete('/downloads/:id', (req, res) => {
  const ok = downloadService.cancel(req.params.id)
  res.json({ canceled: ok })
})

export default router
