import "dotenv/config"
import { ConvexHttpClient } from "convex/browser"

import { createPrismaClient } from "./utils/prisma-client.mjs"

const prisma = createPrismaClient()

function toMillis(date) {
  return date instanceof Date ? date.getTime() : date ? new Date(date).getTime() : undefined
}

function normalizeString(value, fallback = "") {
  if (!value) return fallback
  return value.trim()
}

function slugify(value) {
  return normalizeString(value)
    .toLowerCase()
    .replace(/[^a-z0-9\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-") || undefined
}

function normalizePrismaSlaSnapshot(snapshot) {
  if (!snapshot || typeof snapshot !== "object") return undefined
  const record = snapshot
  const pauseStatuses =
    Array.isArray(record.pauseStatuses) && record.pauseStatuses.length > 0
      ? record.pauseStatuses.filter((value) => typeof value === "string")
      : undefined

  const normalized = {
    categoryId: typeof record.categoryId === "string" ? record.categoryId : undefined,
    categoryName: typeof record.categoryName === "string" ? record.categoryName : undefined,
    priority: typeof record.priority === "string" ? record.priority : undefined,
    responseTargetMinutes: typeof record.responseTargetMinutes === "number" ? record.responseTargetMinutes : undefined,
    responseMode: typeof record.responseMode === "string" ? record.responseMode : undefined,
    solutionTargetMinutes: typeof record.solutionTargetMinutes === "number" ? record.solutionTargetMinutes : undefined,
    solutionMode: typeof record.solutionMode === "string" ? record.solutionMode : undefined,
    alertThreshold: typeof record.alertThreshold === "number" ? record.alertThreshold : undefined,
    pauseStatuses,
  }

  return Object.values(normalized).some((value) => value !== undefined) ? normalized : undefined
}

async function main() {
  const tenantId = process.env.SYNC_TENANT_ID || "tenant-atlas"
  const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL || "http://127.0.0.1:3210"
  const secret = process.env.CONVEX_SYNC_SECRET

  if (!secret) {
    console.error("CONVEX_SYNC_SECRET não configurado. Configure no .env.")
    process.exit(1)
  }

  const [users, queues, tickets, companies] = await Promise.all([
    prisma.user.findMany({
      include: {
        teams: {
          include: { team: true },
        },
        company: true,
      },
    }),
    prisma.queue.findMany(),
    prisma.ticket.findMany({
      include: {
        requester: true,
        assignee: true,
        queue: true,
        company: true,
        comments: {
          include: {
            author: true,
          },
        },
        events: true,
      },
      orderBy: { createdAt: "asc" },
    }),
    prisma.company.findMany(),
  ])

  const userSnapshot = users.map((user) => ({
    email: user.email,
    name: normalizeString(user.name, user.email),
    role: user.role,
    avatarUrl: user.avatarUrl ?? undefined,
    teams: user.teams
      .map((membership) => membership.team?.name)
      .filter((name) => Boolean(name) && typeof name === "string"),
    companySlug: user.company?.slug ?? undefined,
  }))

  const queueSnapshot = queues.map((queue) => ({
    name: normalizeString(queue.name, queue.slug ?? queue.id),
    slug: queue.slug ? queue.slug : normalizeString(queue.name, queue.id).toLowerCase().replace(/\s+/g, "-"),
  }))

  const referenceFallbackStart = 41000
  let referenceCounter = referenceFallbackStart

  const ticketSnapshot = tickets.map((ticket) => {
    const reference = ticket.reference && ticket.reference > 0 ? ticket.reference : ++referenceCounter
    const requesterEmail = ticket.requester?.email ?? userSnapshot[0]?.email ?? "unknown@example.com"
    const assigneeEmail = ticket.assignee?.email ?? undefined
    const queueSlug = ticket.queue?.slug ?? slugify(ticket.queue?.name)
    const companySlug = ticket.company?.slug ?? ticket.requester?.company?.slug ?? undefined

    return {
      reference,
      subject: normalizeString(ticket.subject, `Ticket ${reference}`),
      summary: ticket.summary ?? undefined,
      status: ticket.status,
      priority: ticket.priority,
      channel: ticket.channel,
      queueSlug: queueSlug ?? undefined,
      requesterEmail,
      assigneeEmail,
      companySlug,
      dueAt: toMillis(ticket.dueAt) ?? undefined,
      firstResponseAt: toMillis(ticket.firstResponseAt) ?? undefined,
      resolvedAt: toMillis(ticket.resolvedAt) ?? undefined,
      closedAt: toMillis(ticket.closedAt) ?? undefined,
      createdAt: toMillis(ticket.createdAt) ?? Date.now(),
      updatedAt: toMillis(ticket.updatedAt) ?? Date.now(),
      tags: Array.isArray(ticket.tags) ? ticket.tags : undefined,
      slaSnapshot: normalizePrismaSlaSnapshot(ticket.slaSnapshot),
      slaResponseDueAt: toMillis(ticket.slaResponseDueAt),
      slaSolutionDueAt: toMillis(ticket.slaSolutionDueAt),
      slaResponseStatus: ticket.slaResponseStatus ?? undefined,
      slaSolutionStatus: ticket.slaSolutionStatus ?? undefined,
      slaPausedAt: toMillis(ticket.slaPausedAt),
      slaPausedBy: ticket.slaPausedBy ?? undefined,
      slaPausedMs: typeof ticket.slaPausedMs === "number" ? ticket.slaPausedMs : undefined,
      comments: ticket.comments.map((comment) => ({
        authorEmail: comment.author?.email ?? requesterEmail,
        visibility: comment.visibility,
        body: comment.body,
        createdAt: toMillis(comment.createdAt) ?? Date.now(),
        updatedAt: toMillis(comment.updatedAt) ?? Date.now(),
      })),
      events: ticket.events.map((event) => ({
        type: event.type,
        payload: event.payload ?? {},
        createdAt: toMillis(event.createdAt) ?? Date.now(),
      })),
    }
  })

  const companySnapshot = companies.map((company) => ({
    slug: company.slug ?? slugify(company.name),
    name: company.name,
    cnpj: company.cnpj ?? undefined,
    domain: company.domain ?? undefined,
    phone: company.phone ?? undefined,
    description: company.description ?? undefined,
    address: company.address ?? undefined,
    createdAt: toMillis(company.createdAt) ?? Date.now(),
    updatedAt: toMillis(company.updatedAt) ?? Date.now(),
  }))

  const client = new ConvexHttpClient(convexUrl)

  const result = await client.mutation("migrations:importPrismaSnapshot", {
    secret,
    snapshot: {
      tenantId,
      companies: companySnapshot,
      users: userSnapshot,
      queues: queueSnapshot,
      tickets: ticketSnapshot,
    },
  })

  console.log("Sincronização concluída:", result)
}

main()
  .catch((error) => {
    console.error(error)
    process.exitCode = 1
  })
  .finally(async () => {
    await prisma.$disconnect()
  })
