const badgeDb = require("../db/badge.db")
const userBadgeDb = require("../db/userBadge.db")
const userDb = require("../db/user.db")

function assertPositiveInt(value, name) {
  const num = Number(value)
  if (!Number.isInteger(num) || num <= 0) throw new Error(`Geçersiz ${name}.`)
  return num
}

function normalizeOptionalString(value) {
  if (value === undefined) return undefined
  if (value === null) return null
  const trimmed = String(value).trim()
  return trimmed ? trimmed : null
}

async function listBadges() {
  return badgeDb.listBadges()
}

async function createBadge({ name, iconUrl, description }) {
  const normalizedName = String(name || "").trim()
  if (!normalizedName) throw new Error("Badge adı zorunlu.")

  return badgeDb.createBadge({
    name: normalizedName,
    iconUrl: normalizeOptionalString(iconUrl),
    description: normalizeOptionalString(description),
  })
}

async function updateBadge(badgeId, { name, iconUrl, description }) {
  const id = assertPositiveInt(badgeId, "badgeId")
  const data = {}

  if (name !== undefined) {
    const normalizedName = String(name || "").trim()
    if (!normalizedName) throw new Error("Badge adı zorunlu.")
    data.name = normalizedName
  }
  if (iconUrl !== undefined) data.iconUrl = normalizeOptionalString(iconUrl)
  if (description !== undefined) data.description = normalizeOptionalString(description)

  if (!Object.keys(data).length) throw new Error("Güncellenecek alan yok.")

  return badgeDb.updateBadge({ id }, data)
}

async function assignBadgeToUser({ userId, badgeId, earnedAt }) {
  const uid = assertPositiveInt(userId, "userId")
  const bid = assertPositiveInt(badgeId, "badgeId")
  const earnedAtDate = earnedAt ? new Date(earnedAt) : new Date()
  if (Number.isNaN(earnedAtDate.getTime())) throw new Error("Geçersiz kazanılma tarihi.")

  const [user, badge] = await Promise.all([
    userDb.findUser({ id: uid }, { select: { id: true } }),
    badgeDb.findBadge({ id: bid }, { select: { id: true } }),
  ])
  if (!user) throw new Error("Kullanıcı bulunamadı.")
  if (!badge) throw new Error("Badge bulunamadı.")

  return userBadgeDb.createUserBadge({
    userId: uid,
    badgeId: bid,
    earnedAt: earnedAtDate,
  })
}

async function removeBadgeFromUser({ userId, badgeId }) {
  const uid = assertPositiveInt(userId, "userId")
  const bid = assertPositiveInt(badgeId, "badgeId")
  return userBadgeDb.deleteUserBadge({
    userId_badgeId: { userId: uid, badgeId: bid },
  })
}

module.exports = {
  listBadges,
  createBadge,
  updateBadge,
  assignBadgeToUser,
  removeBadgeFromUser,
}
