// services/user.service.js
const userDB = require("../db/user.db")
const dealDB = require("../db/deal.db")
const commentDB = require("../db/comment.db")
const dealService = require("./deal.service")

const PROFILE_PAGE_SIZE = 15

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

function buildPagination({ page, total, limit }) {
  const safeTotal = Number.isFinite(total) ? Math.max(0, total) : 0
  const safeLimit = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : PROFILE_PAGE_SIZE
  return {
    page,
    total: safeTotal,
    totalPages: safeTotal === 0 ? 0 : Math.ceil(safeTotal / safeLimit),
    limit: safeLimit,
  }
}

async function getUserProfileByUsername(userName) {
  const username = String(userName).trim()
  if (!username) throw new Error("username zorunlu")

  const user = await userDB.findUser(
    { username },
    {
      select: {
        id: true,
        username: true,
        email: true,
        avatarUrl: true,
        createdAt: true,
        userBadges: {
          orderBy: { earnedAt: "desc" },
          select: {
            earnedAt: true,
            badge: { select: { id: true, name: true, iconUrl: true, description: true } },
          },
        },
      },
    }
  )

  if (!user) {
    const err = new Error("Kullanıcı bulunamadı.")
    err.statusCode = 404
    throw err
  }

  const commentsPage = 1
  const dealsPage = 1

  const [dealAgg, totalComments, comments, userDeals] = await Promise.all([
    dealDB.aggregateDeals({ userId: user.id, status: { in: ["ACTIVE", "EXPIRED"] } }),
    commentDB.countComments({ userId: user.id }),
    commentDB.findComments(
      { userId: user.id },
      {
        orderBy: { createdAt: "desc" },
        skip: (commentsPage - 1) * PROFILE_PAGE_SIZE,
        take: PROFILE_PAGE_SIZE,
        include: {
          user: { select: { id: true, username: true, avatarUrl: true } },
          deal: { select: { id: true, title: true } },
        },
      }
    ),
    dealService.getDeals({
      preset: "USER_PUBLIC",
      targetUserId: user.id,
      viewer: null,
      page: dealsPage,
      limit: PROFILE_PAGE_SIZE,
    }),
  ])

  const totalDeals = dealAgg?._count?._all ?? 0
  const stats = {
    totalLikes: dealAgg?._sum?.score ?? 0,
    totalComments: totalComments ?? 0,
    totalShares: totalDeals,
    totalDeals,
  }

  return {
    user,
    stats,
    deals: userDeals.results,
    comments,
    badges: user.userBadges || [],
    dealsPagination: buildPagination({
      page: userDeals.page ?? dealsPage,
      total: userDeals.total ?? 0,
      limit: PROFILE_PAGE_SIZE,
    }),
    commentsPagination: buildPagination({
      page: commentsPage,
      total: totalComments ?? 0,
      limit: PROFILE_PAGE_SIZE,
    }),
  }
}

async function getUserCommentsByUsername(userName, { page = 1, limit = PROFILE_PAGE_SIZE } = {}) {
  const username = String(userName).trim()
  if (!username) throw new Error("username zorunlu")

  const user = await userDB.findUser(
    { username },
    { select: { id: true } }
  )
  if (!user) {
    const err = new Error("Kullanici bulunamadi.")
    err.statusCode = 404
    throw err
  }

  const safePage = normalizePage(page)
  const safeLimit = PROFILE_PAGE_SIZE
  const skip = (safePage - 1) * safeLimit

  const [total, results] = await Promise.all([
    commentDB.countComments({ userId: user.id }),
    commentDB.findComments(
      { userId: user.id },
      {
        orderBy: { createdAt: "desc" },
        skip,
        take: safeLimit,
        include: {
          user: { select: { id: true, username: true, avatarUrl: true } },
          deal: { select: { id: true, title: true } },
        },
      }
    ),
  ])

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

async function getUserDealsByUsername(userName, { page = 1, limit = PROFILE_PAGE_SIZE, viewer = null } = {}) {
  const username = String(userName).trim()
  if (!username) throw new Error("username zorunlu")

  const user = await userDB.findUser(
    { username },
    { select: { id: true } }
  )
  if (!user) {
    const err = new Error("Kullanici bulunamadi.")
    err.statusCode = 404
    throw err
  }

  const safePage = normalizePage(page)
  const safeLimit = PROFILE_PAGE_SIZE

  const isSelfProfile = viewer?.userId && Number(viewer.userId) === Number(user.id)
  const preset = isSelfProfile ? "MY" : "USER_PUBLIC"

  const payload = await dealService.getDeals({
    preset,
    targetUserId: user.id,
    viewer,
    page: safePage,
    limit: safeLimit,
  })

  return {
    page: payload.page ?? safePage,
    total: payload.total ?? 0,
    totalPages: payload.totalPages ?? 0,
    limit: safeLimit,
    results: payload.results ?? [],
  }
}

module.exports = {
  getUserProfileByUsername,
  getUserCommentsByUsername,
  getUserDealsByUsername,
}
