const http = require('http')
const path = require('path')
const fs = require('fs')
const express = require('express')
const cors = require('cors')
const { WebSocketServer } = require('ws')
const routes = require('./routes')
const { getSituation } = require('./situationData')

const swaggerUi = require('swagger-ui-express')
const openApiSpec = require('./openapi')

const app = express()
const PORT = process.env.API_PORT || 3001

app.set('trust proxy', 1)
app.use(cors())
app.use(express.json())

// Swagger 文档
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiSpec))

app.use('/api', routes)
app.get('/api/health', (_, res) => res.json({ ok: true }))
app.post('/api/crawler/notify', (_, res) => {
  notifyCrawlerUpdate()
  res.json({ ok: true })
})

// 生产环境：提供前端静态文件
const distPath = path.join(__dirname, '..', 'dist')
if (fs.existsSync(distPath)) {
  app.use(express.static(distPath))
  app.get('*', (req, res, next) => {
    if (!req.path.startsWith('/api') && req.path !== '/ws') {
      res.sendFile(path.join(distPath, 'index.html'))
    } else next()
  })
}

const server = http.createServer(app)

const wss = new WebSocketServer({ server, path: '/ws' })
wss.on('connection', (ws) => {
  ws.send(JSON.stringify({ type: 'situation', data: getSituation() }))
})
function broadcastSituation() {
  try {
    const data = JSON.stringify({ type: 'situation', data: getSituation() })
    wss.clients.forEach((c) => {
      if (c.readyState === 1) c.send(data)
    })
  } catch (_) {}
}
setInterval(broadcastSituation, 3000)

// 供爬虫调用：更新 situation.updated_at 并立即广播
function notifyCrawlerUpdate() {
  try {
    const db = require('./db')
    db.prepare("INSERT OR REPLACE INTO situation (id, data, updated_at) VALUES (1, '{}', ?)").run(new Date().toISOString())
    broadcastSituation()
  } catch (_) {}
}

server.listen(PORT, () => {
  console.log(`API + WebSocket running at http://localhost:${PORT}`)
  console.log(`Swagger docs at http://localhost:${PORT}/api-docs`)
})
