import "dotenv/config"
import { prisma } from "../src/server/db"

type DomainViewResponse = {
  domains?: Array<{
    domain?: {
      fulldomain?: string
    }
  }>
}

type SubaccountsResponse = {
  subaccounts?: Array<{
    id?: string
    subaccount_id?: string
    subaccountId?: string
  }>
  continue_token?: string
}

const API_KEY = process.env.SMTP2GO_API_KEY
if (!API_KEY) throw new Error("Missing SMTP2GO_API_KEY")

async function smtp2goPost<T>(path: string, body: Record<string, unknown>): Promise<T> {
  const res = await fetch(`https://api.smtp2go.com/v3${path}`, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "accept": "application/json",
      "X-Smtp2go-Api-Key": API_KEY,
    } as Record<string, string>,
    body: JSON.stringify(body),
  })
  const json = (await res.json().catch(() => ({}))) as { data?: T; error?: string }
  if (!res.ok) {
    throw new Error(json?.error || `SMTP2GO_HTTP_${res.status}`)
  }
  return (json?.data ?? (json as unknown)) as T
}

async function searchAllSubaccounts(): Promise<SubaccountsResponse["subaccounts"]> {
  const out: NonNullable<SubaccountsResponse["subaccounts"]> = []
  let continueToken: string | undefined
  do {
    const data = await smtp2goPost<SubaccountsResponse>("/subaccounts/search", {
      page_size: 100,
      ...(continueToken ? { continue_token: continueToken } : {}),
    })
    const items = Array.isArray(data?.subaccounts) ? data.subaccounts : []
    out.push(...items)
    continueToken = data?.continue_token
  } while (continueToken)
  return out
}

async function viewDomains(subaccountId: string): Promise<DomainViewResponse> {
  return smtp2goPost<DomainViewResponse>("/domain/view", { subaccount_id: subaccountId })
}

const args = new Set(process.argv.slice(2))
const force = args.has("--force")
const limitArg = process.argv.find((a) => a.startsWith("--limit="))
const limit = limitArg ? Number(limitArg.split("=")[1]) : undefined

async function main() {
  const list = (await searchAllSubaccounts()) ?? []
  const targets = limit ? list.slice(0, limit) : list

  let updated = 0
  let skipped = 0
  let missing = 0

  for (const sa of targets) {
    const subId = sa.subaccount_id ?? sa.subaccountId ?? sa.id
    if (!subId) continue

    const existing = await prisma.subaccountMeta.findUnique({
      where: { subaccountId: String(subId) },
      select: { domain: true },
    })
    if (existing?.domain && !force) {
      skipped++
      continue
    }

    try {
      const res = (await viewDomains(String(subId))) as DomainViewResponse
      const domain = res?.domains?.[0]?.domain?.fulldomain?.trim() ?? null
      if (!domain) {
        missing++
        continue
      }
      await prisma.subaccountMeta.upsert({
        where: { subaccountId: String(subId) },
        update: { domain },
        create: { subaccountId: String(subId), domain },
      })
      updated++
      // small delay to avoid bursts
      await new Promise((r) => setTimeout(r, 150))
    } catch (e) {
      console.error("Erro ao consultar domínio", subId, e)
    }
  }

  console.log(`Atualizados: ${updated}`)
  console.log(`Ignorados (já tinham domínio): ${skipped}`)
  console.log(`Sem domínio encontrado: ${missing}`)
}

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