import 'dotenv/config'
import { PrismaService } from "src/prisma/prisma.service"
import * as argon from "@node-rs/argon2"

const prisma = new PrismaService()

/* ------------------ helpers ------------------ */

function randomBetween(min: number, max: number) {
  return Math.random() * (max - min) + min
}

function randomInt(min: number, max: number) {
  return Math.floor(randomBetween(min, max + 1))
}

function pick<T>(arr: T[]): T {
  return arr[Math.floor(Math.random() * arr.length)]
}

/* ------------------ dummy pools ------------------ */

const firstNames = [
  "Agus", "Budi", "Made", "Putu", "Ketut", "Wayan",
  "Sari", "Dewi", "Putri", "Ayu",
  "Rudi", "Joko", "Indra", "Rina", "Dian"
]

const lastNames = [
  "Saputra", "Wijaya", "Santoso", "Pratama",
  "Utama", "Mahendra", "Putra", "Suryadi"
]

const streets = [
  "Melati", "Kenanga", "Anggrek", "Mawar",
  "Cempaka", "Sudirman", "Diponegoro"
]

/* ------------------ generators ------------------ */

function generateName() {
  return `${pick(firstNames)} ${pick(lastNames)}`
}

function generatePhone() {
  return `08${randomInt(1000000000, 9999999999)}`
}

function generateKTP() {
  return String(randomInt(1000000000000000, 9999999999999999))
}

function generateAddress() {
  return `Jl. ${pick(streets)} No ${randomInt(1, 200)}`
}

function generateBankAccountNo() {
  return String(randomInt(1000000000, 9999999999))
}

/* ------------------ sanitize customers ------------------ */

async function sanitizeCustomers() {
  console.log("Sanitizing customers...")

  const customers = await prisma.customer.findMany({
    select: { id: true }
  })

  for (const c of customers) {
    await prisma.customer.update({
      where: { id: c.id },
      data: {
        fullName: generateName(),
        phoneNumber: generatePhone(),
        ktpNumber: Math.random() > 0.3 ? generateKTP() : null,
        ktpPhotoUrl: null,
        address: generateAddress(),
      }
    })
  }

  console.log(`Sanitized ${customers.length} customers`)
}

/* ------------------ sanitize transactions ------------------ */

async function sanitizeTransactions() {
  console.log("Sanitizing transactions...")

  const transactions = await prisma.transaction.findMany({
    select: { id: true }
  })

  for (const trx of transactions) {
    await prisma.transaction.update({
      where: { id: trx.id },
      data: {
        bankAccountNo: generateBankAccountNo(),
        bankAccountName: generateName(),
      }
    })
  }

  console.log(`Sanitized ${transactions.length} transactions`)
}

/* ------------------ sanitize users (argon2) ------------------ */

async function sanitizeUsers() {
  console.log("Resetting user passwords...")

  const DEFAULT_PASSWORD = "password123"

  // same hashing as seeder
  const hashedPassword = await argon.hash(DEFAULT_PASSWORD)

  const users = await prisma.user.findMany({
    select: { id: true }
  })

  for (const u of users) {
    await prisma.user.update({
      where: { id: u.id },
      data: {
        hash: hashedPassword,
      }
    })
  }

  console.log(`Reset ${users.length} user passwords`)
  console.log(`Default password: ${DEFAULT_PASSWORD}`)
}

/* ------------------ main ------------------ */

async function main() {
  console.log("Starting data sanitization...")

  await sanitizeCustomers()
  await sanitizeTransactions()
  await sanitizeUsers()

  console.log("Sanitization complete ✅")
}

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