import type { NextFunction, Request, Response } from 'express'
import express from 'express'
import process from 'node:process'

import adminRouter from './routes/admin.js'
import affiliateDashRouter from './routes/affiliate-dash.js'
import collectRouter from './routes/collect.js'
import filesRouter from './routes/files.js'
import claimsRouter from './routes/claims.js'
import kuaishouFeifeiRouter from './routes/kuaishou-feifei.js'
import kuaishouIndustryRouter from './routes/kuaishou-industry.js'
import open91Router from './routes/open-91.js'
import shortLinksRouter from './routes/short-links.js'
import workerRouter from './routes/worker.js'
import { accessLogMiddleware } from './middleware/access-log.js'
import { createCorsMiddleware } from './middleware/cors.js'
import { buildHealthPayload, type StartupState } from './startup/state.js'
import type { RuntimeConfig } from './types/runtime-config.js'
import { buildSuccessPayload, sendRouteError } from './utils/http.js'

type CreateAppOptions = {
  startupState: StartupState
  isShutdownStarted: () => boolean
  config: RuntimeConfig
}

export function createApp({ startupState, isShutdownStarted, config }: CreateAppOptions) {
  const app = express()

  // 部署在反代（Caddy）之后时让 req.ip 取 X-Forwarded-For 的真实客户端地址；限流、访问日志与登录设备记录都依赖它。
  if (config.server?.trustProxy !== undefined && config.server?.trustProxy !== null) {
    app.set('trust proxy', config.server.trustProxy)
  }

  app.use(accessLogMiddleware)
  app.use(createCorsMiddleware(config))
  app.use(
    express.json({
      limit: '2mb',
      verify: (req, _res, buffer) => {
        ;(req as Request).rawBody = buffer.toString('utf8')
      },
    }),
  )
  app.use(express.urlencoded({ extended: true }))

  app.get('/health', (_req, res) => {
    res.json(
      buildSuccessPayload(
        buildHealthPayload(startupState, isShutdownStarted()),
        startupState.core.ready ? 'ready' : 'starting',
      ),
    )
  })

  app.get('/health/live', (_req, res) => {
    res.json(
      buildSuccessPayload({
        status: isShutdownStarted() ? 'shutting_down' : 'alive',
        pid: process.pid,
        mode: 'kuaishou-lite',
      }),
    )
  })

  app.get('/health/ready', (_req, res) => {
    if (startupState.core.ready) {
      res.json(buildSuccessPayload(buildHealthPayload(startupState, isShutdownStarted()), 'ready'))
      return
    }

    res.status(503).json({
      code: 1,
      msg: startupState.core.lastError || '服务启动中，请稍后重试',
      errorCode: 'service_not_ready',
      time: Math.floor(Date.now() / 1000),
      data: buildHealthPayload(startupState, isShutdownStarted()),
    })
  })

  app.use((req, res, next) => {
    if (startupState.core.ready) {
      next()
      return
    }

    res.status(503).json({
      code: 1,
      msg: startupState.core.lastError || '服务启动中，请稍后重试',
      errorCode: 'service_not_ready',
      time: Math.floor(Date.now() / 1000),
      data: {
        startup: {
          phase: startupState.phase,
          attemptCount: startupState.core.attemptCount,
          lastAttemptAt: startupState.core.lastAttemptAt,
        },
      },
    })
  })

  app.use('/api/v1/open/affiliate-dash', affiliateDashRouter)
  app.use('/api/v1/open/91', open91Router)
  app.use('/api/v1/open/kuaishou-industry', kuaishouIndustryRouter)
  app.use('/api/v1/open/kuaishou-feifei', kuaishouFeifeiRouter)
  app.use('/api/v1/claim', claimsRouter)
  app.use('/api/v1/collect', collectRouter)
  app.use('/api/v1/files', filesRouter)
  app.use('/api/v1/worker', workerRouter)
  app.use('/api/v1/admin', adminRouter)
  app.use('/s', shortLinksRouter)

  app.use((err: unknown, _req: Request, res: Response, _next: NextFunction) => {
    sendRouteError(res, err, '服务内部错误', '[global]')
  })

  return app
}
