const dealDB = require("../db/deal.db")
const dealReportDB = require("../db/dealReport.db")
const { queueDealReportStatusUpdate } = require("./redis/dbSync.service")

const PAGE_LIMIT = 20
const ALLOWED_REASONS = new Set([
  "EXPIRED",
  "WRONG_PRICE",
  "MISLEADING",
  "SPAM",
  "OTHER",
])
const ALLOWED_STATUSES = new Set(["OPEN", "REVIEWED", "CLOSED"])

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

function normalizePage(value) {
  const num = Number(value)
  if (!Number.isInteger(num) || num < 1) return 1
  return num
}

function normalizeReason(value) {
  const normalized = String(value || "").trim().toUpperCase()
  return ALLOWED_REASONS.has(normalized) ? normalized : null
}

function normalizeStatus(value) {
  if (!value) return null
  const normalized = String(value || "").trim().toUpperCase()
  return ALLOWED_STATUSES.has(normalized) ? normalized : null
}

async function createDealReport({ dealId, userId, reason, note }) {
  const did = assertPositiveInt(dealId, "dealId")
  const uid = assertPositiveInt(userId, "userId")
  const normalizedReason = normalizeReason(reason)
  if (!normalizedReason) {
    const err = new Error("Gecersiz reason.")
    err.statusCode = 400
    throw err
  }

  const deal = await dealDB.findDeal({ id: did }, { select: { id: true } })
  if (!deal) {
    const err = new Error("Deal bulunamadi.")
    err.statusCode = 404
    throw err
  }

  await dealReportDB.upsertDealReport({
    dealId: did,
    userId: uid,
    reason: normalizedReason,
    note: note ? String(note).trim().slice(0, 500) : null,
  })

  return { reported: true }
}

async function listDealReports({ page = 1, status = null, dealId = null, userId = null } = {}) {
  const safePage = normalizePage(page)
  const skip = (safePage - 1) * PAGE_LIMIT

  const where = {}
  const normalizedStatus = normalizeStatus(status)
  if (normalizedStatus) where.status = normalizedStatus
  if (Number.isInteger(Number(dealId))) where.dealId = Number(dealId)
  if (Number.isInteger(Number(userId))) where.userId = Number(userId)

  const [total, reports] = await Promise.all([
    dealReportDB.countDealReports(where),
    dealReportDB.listDealReports(where, {
      skip,
      take: PAGE_LIMIT,
      orderBy: { createdAt: "asc" },
      include: {
        deal: { select: { id: true, title: true, status: true } },
        user: { select: { id: true, username: true } },
      },
    }),
  ])

  return {
    page: safePage,
    total,
    totalPages: total ? Math.ceil(total / PAGE_LIMIT) : 0,
    results: reports,
  }
}

async function updateDealReportStatus({ reportId, status }) {
  const rid = assertPositiveInt(reportId, "reportId")
  const normalizedStatus = normalizeStatus(status)
  if (!normalizedStatus) {
    const err = new Error("Gecersiz status.")
    err.statusCode = 400
    throw err
  }

  queueDealReportStatusUpdate({
    reportId: rid,
    status: normalizedStatus,
    updatedAt: new Date().toISOString(),
  }).catch((err) => console.error("DB sync dealReport status failed:", err?.message || err))

  return { reportId: rid, status: normalizedStatus }
}

module.exports = {
  createDealReport,
  listDealReports,
  updateDealReportStatus,
}
