import type { FastifyPluginAsyncZod } from "@fastify/type-provider-zod"
import {
  getAlertsMeta,
  getTelegramBotToken,
  getTelegramMessageThreadIdForApi,
  getTelegramPublic,
  listAlertGroups,
  listAlertRules,
  listMergedHistory,
  replaceAlertsConfig,
  formatAlertRuleTestTelegramText,
  sendTelegramAlertMessage,
  updateTelegramSettings,
} from "../services/alerts-service.js"
import {
  putRulesSchema,
  putTelegramSchema,
  testTelegramSchema,
} from "@mmapp/contracts/alerts"

const alertsRoutes: FastifyPluginAsyncZod = async (app) => {
  app.get("/alerts", async (_req, reply) => {
    const tg = getTelegramPublic()
    const connected = tg.tokenConfigured && Boolean(tg.chatId?.trim())
    return reply.send({
      telegram: { ...tg, connected },
      groups: listAlertGroups(),
      rules: listAlertRules(),
      history: listMergedHistory(),
      meta: getAlertsMeta(),
    })
  })

  app.put("/alerts/rules", async (req, reply) => {
    const parsed = putRulesSchema.safeParse(req.body)
    if (!parsed.success) {
      return reply.status(400).send({ error: "Некорректное тело запроса", details: parsed.error.flatten() })
    }
    const groups =
      parsed.data.groups ??
      listAlertGroups().map((g) => ({
        id: g.id,
        name: g.name,
        combineMode: g.combineMode,
        enabled: g.enabled,
        cooldownOverride: g.cooldownOverride,
      }))
    const rules = parsed.data.rules.map((r) => ({
      id: r.id,
      name: r.name,
      type: r.type,
      target: r.target,
      targets: r.targets,
      groupId: r.groupId ?? null,
      condition: r.condition,
      conditions:
        r.conditions && r.conditions.length > 0
          ? r.conditions.map((c) => c.trim()).filter(Boolean)
          : r.condition?.trim()
            ? [r.condition.trim()]
            : [],
      severity: r.severity,
      enabled: r.enabled,
      cooldown: r.cooldown,
      confirmStabilitySec: r.confirmStabilitySec ?? null,
      recoveryMode: r.recoveryMode ?? "always",
      recoveryStabilitySec: r.recoveryStabilitySec ?? null,
      chatId: r.chatId,
    }))
    replaceAlertsConfig({ groups, rules })
    return reply.send({ ok: true, groups: listAlertGroups(), rules: listAlertRules() })
  })

  app.put("/alerts/telegram", async (req, reply) => {
    const parsed = putTelegramSchema.safeParse(req.body)
    if (!parsed.success) {
      return reply.status(400).send({ error: "Некорректное тело запроса", details: parsed.error.flatten() })
    }
    const next = updateTelegramSettings({
      token: parsed.data.token,
      chatId: parsed.data.chatId,
      messageThreadId: parsed.data.messageThreadId,
    })
    const connected = next.tokenConfigured && Boolean(next.chatId?.trim())
    return reply.send({ ok: true, telegram: { ...next, connected } })
  })

  app.post("/alerts/telegram/test", async (req, reply) => {
    const parsed = testTelegramSchema.safeParse(req.body ?? {})
    if (!parsed.success) {
      return reply.status(400).send({ error: "Некорректное тело запроса", details: parsed.error.flatten() })
    }
    const fromDb = getTelegramBotToken()
    const token = (parsed.data.token?.trim() || fromDb).trim()
    const pub = getTelegramPublic()
    const chatId = (parsed.data.chatId?.trim() || pub.chatId || "").trim()
    if (!token) {
      return reply.status(400).send({ error: "Не задан Bot Token (сохраните в БД или передайте в запросе)" })
    }
    if (!chatId) {
      return reply.status(400).send({ error: "Не задан Chat ID" })
    }
    const threadId =
      parsed.data.messageThreadId != null && parsed.data.messageThreadId >= 1
        ? parsed.data.messageThreadId
        : getTelegramMessageThreadIdForApi()
    const text = parsed.data.rulePreview
      ? formatAlertRuleTestTelegramText(parsed.data.rulePreview)
      : "MikroTik Manager — тест оповещений (Telegram)."
    const send = await sendTelegramAlertMessage({
      text,
      token: parsed.data.token?.trim() || undefined,
      chatId,
      messageThreadId: threadId,
    })
    if (!send.ok) {
      return reply.status(502).send({ ok: false, error: send.error })
    }
    return reply.send({ ok: true })
  })
}

export default alertsRoutes
