import { mutation, query } from "./_generated/server"
import { v } from "convex/values"

export const log = mutation({
  args: {
    tenantId: v.string(),
    companyId: v.optional(v.id("companies")),
    companyName: v.string(),
    usagePct: v.number(),
    threshold: v.number(),
    range: v.string(),
    recipients: v.array(v.string()),
    deliveredCount: v.number(),
  },
  handler: async (ctx, args) => {
    const now = Date.now()
    await ctx.db.insert("alerts", {
      tenantId: args.tenantId,
      companyId: args.companyId,
      companyName: args.companyName,
      usagePct: args.usagePct,
      threshold: args.threshold,
      range: args.range,
      recipients: args.recipients,
      deliveredCount: args.deliveredCount,
      createdAt: now,
    })
  },
})

export const list = query({
  args: {
    tenantId: v.string(),
    viewerId: v.id("users"),
    limit: v.optional(v.number()),
    companyId: v.optional(v.id("companies")),
    start: v.optional(v.number()),
    end: v.optional(v.number()),
  },
  handler: async (ctx, { tenantId, viewerId, limit, companyId, start, end }) => {
    // Only admins can see the full alerts log
    const user = await ctx.db.get(viewerId)
    if (!user || user.tenantId !== tenantId || (user.role ?? "").toUpperCase() !== "ADMIN") {
      return []
    }
    let items = await ctx.db
      .query("alerts")
      .withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
      .take(100)
    if (companyId) items = items.filter((a) => a.companyId === companyId)
    if (typeof start === "number") items = items.filter((a) => a.createdAt >= start)
    if (typeof end === "number") items = items.filter((a) => a.createdAt < end)
    return items
      .sort((a, b) => b.createdAt - a.createdAt)
      .slice(0, Math.max(1, Math.min(limit ?? 200, 500)))
  },
})

export const managersForCompany = query({
  args: { tenantId: v.string(), companyId: v.id("companies") },
  handler: async (ctx, { tenantId, companyId }) => {
    const users = await ctx.db
      .query("users")
      .withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", companyId))
      .take(100)
    return users.filter((u) => (u.role ?? "").toUpperCase() === "MANAGER")
  },
})

export const lastForCompanyBySlug = query({
  args: { tenantId: v.string(), slug: v.string() },
  handler: async (ctx, { tenantId, slug }) => {
    const company = await ctx.db
      .query("companies")
      .withIndex("by_tenant_slug", (q) => q.eq("tenantId", tenantId).eq("slug", slug))
      .first()
    if (!company) return null
    const items = await ctx.db
      .query("alerts")
      .withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
      .take(100)
    const matches = items.filter((a) => a.companyId === company._id)
    if (matches.length === 0) return null
    const last = matches.sort((a, b) => b.createdAt - a.createdAt)[0]
    return { createdAt: last.createdAt, usagePct: last.usagePct, threshold: last.threshold }
  },
})

export const lastForCompaniesBySlugs = query({
  args: { tenantId: v.string(), slugs: v.array(v.string()) },
  handler: async (ctx, { tenantId, slugs }) => {
    const result: Record<string, { createdAt: number; usagePct: number; threshold: number } | null> = {}
    // Fetch all alerts once for the tenant
    const alerts = await ctx.db
      .query("alerts")
      .withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
      .take(100)
    // Buscar todas as companies do tenant de uma vez
    const allCompanies = await ctx.db
      .query("companies")
      .withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
      .take(1000)
    const companiesBySlug = new Map(allCompanies.map(c => [c.slug, c]))
    for (const slug of slugs) {
      const company = companiesBySlug.get(slug)
      if (!company) {
        result[slug] = null
        continue
      }
      const matches = alerts.filter((a) => a.companyId === company._id)
      if (matches.length === 0) {
        result[slug] = null
        continue
      }
      const last = matches.sort((a, b) => b.createdAt - a.createdAt)[0]
      result[slug] = { createdAt: last.createdAt, usagePct: last.usagePct, threshold: last.threshold }
    }
    return result
  },
})

export const tenantIds = query({
  args: {},
  handler: async (ctx) => {
    // Limita a 1000 companies para evitar OOM
    const companies = await ctx.db.query("companies").take(1000)
    return Array.from(new Set(companies.map((c) => c.tenantId)))
  },
})

export const existsForCompanyRange = query({
  args: { tenantId: v.string(), companyId: v.id("companies"), start: v.number(), end: v.number() },
  handler: async (ctx, { tenantId, companyId, start, end }) => {
    // Limita a 500 alerts para evitar OOM e faz filtragem eficiente
    const items = await ctx.db
      .query("alerts")
      .withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
      .take(500)
    return items.some((a) => a.companyId === companyId && a.createdAt >= start && a.createdAt < end)
  },
})
