/* eslint-disable eqeqeq */
/* eslint-disable camelcase */
const jwt = require('jsonwebtoken')
const { check, validationResult } = require('express-validator')
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const UserModel = require('../../../models/UserModel')
const AdvertisingModel = require('../../../models/AdvertisingModel')
const fs = require('fs-extra')
const path = require('path')
const AdvertisingTypeModel = require('../../../models/AdvertisingTypeModel')
const AdvertisingCategoryModel = require('../../../models/AdvertisingCategoryModel')
const AdvertisingFeaturesModel = require('../../../models/AdvertisingFeaturesModel')
const AdvertisingLikeModel = require('../../../models/AdvertisingLikeModel')
const AdvertisingComment = require('../../../models/AdvertisingCommentModel')
const AdvertisingRatingModel = require('../../../models/AdvertisingRatingModel')
const AdvertisingProfileModel = require('../../../models/AdvertisingProfile')

const createAdvertisingValidationRules = () => {
  return [
    check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),
    check('category').notEmpty().withMessage('دسته‌بندی نمی‌تواند خالی باشد'),
    check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),
    check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد')
  ]
}
// تابع کمکی برای ذخیره تصاویر
const saveFile = async (file, folder, userName) => {
  const uploadDir = path.join(__dirname, '../../../../storage', folder)
  if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true })

  const uniqueFileName = `${userName}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(file.name)}`
  const filePath = path.join(uploadDir, uniqueFileName)
  await fs.move(file.path, filePath)
  return `/${folder}/${uniqueFileName}`
}

const createAdvertising = async (req, res, next) => {
  try {
    // ✅ بررسی Authorization header
    const authHeader = req.header('Authorization')
    if (!authHeader) return res.status(401).json({ error: true, message: 'Access Denied' })

    const token = authHeader.split(' ')[1]
    if (!token) return res.status(401).json({ error: true, message: 'Access Denied' })

    let decodedToken
    try {
      decodedToken = jwt.verify(token, process.env.APP_SECRET)
    } catch (err) {
      return res.status(401).json({ error: true, message: 'توکن نامعتبر است' })
    }

    const user = await UserModel.findById(decodedToken.id)
    if (!user) return res.status(422).json({ error: true, message: 'شما دسترسی به این بخش ندارید' })

    // ✅ اعتبارسنجی فرم
    const errors = validationResult(req)
    if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() })

    const {
      category,
      title,
      description,
      province,
      city,
      neighbourhood,
      address,
      lat,
      lng,
      services,
      features,
      contactInfo,
      mostDiscountPercentage,
      showDiscount,
      type
    } = req.body

    if (!title || !category || !province || !city) {
      return res.status(422).json({ error: true, message: 'اطلاعات ارسالی اشتباه است' })
    }

    const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
    const cityFind = await CityModel.findOne({ id: city })

    // ✅ مدیریت خدمات و تصاویرشان
    let parsedServices = []
    try {
      parsedServices = services ? JSON.parse(services) : []
    } catch (err) {
      return res.status(422).json({ error: true, message: 'فرمت خدمات اشتباه است' })
    }

    const servicesWithImages = []
    for (const service of parsedServices) {
      const serviceImages = []
      const serviceId = service.id
      const serviceFiles = req.files?.serviceImages?.[serviceId]
      const imageFiles = Array.isArray(serviceFiles) ? serviceFiles : serviceFiles ? [serviceFiles] : []

      for (const file of imageFiles) {
        const imageUrl = await saveFile(file, 'services', user.user_name)
        serviceImages.push(imageUrl)
        service.image = imageUrl
      }
      servicesWithImages.push({ ...service, images: serviceImages })
    }

    // ✅ مدیریت تصاویر تبلیغ
    const imageFiles = Array.isArray(req.files?.images) ? req.files.images : req.files?.images ? [req.files.images] : []
    const images = []
    for (const file of imageFiles) {
      const imageUrl = await saveFile(file, 'advertising', user.user_name)
      images.push(imageUrl)
    }

    // ✅ مدیریت ویژگی‌ها
    let parsedFeatures = []
    try {
      parsedFeatures = features ? JSON.parse(features) : []
    } catch (err) {
      return res.status(422).json({ error: true, message: 'فرمت ویژگی‌ها اشتباه است' })
    }

    // ✅ ایجاد رکورد جدید
    const newAd = new AdvertisingModel({
      title,
      category,
      description,
      province: provinceFind,
      city: cityFind,
      neighbourhood,
      address,
      lat,
      lng,
      images,
      services: servicesWithImages,
      features: parsedFeatures,
      contactInfo,
      creator_id: user._id,
      mostDiscountPercentage,
      showDiscount,
      type
    })

    await newAd.save()

    // ✅ ذخیره اطلاعات تماس برای استفاده بعدی
    if (contactInfo?.saveInfoForNextAds) {
      let advertisingProfile = await AdvertisingProfileModel.findOne({ user: user._id })
      if (advertisingProfile) {
        advertisingProfile.contactInfo = contactInfo
        await advertisingProfile.save()
      } else {
        advertisingProfile = new AdvertisingProfileModel({ user: user._id, contactInfo })
        await advertisingProfile.save()
      }
    }

    return res.status(201).json({
      success: true,
      message: 'ویترین با موفقیت ایجاد شد',
      data: { id: newAd._id }
    })
  } catch (error) {
    next(error)
  }
}
// const getAdvertisings = async (req, res, next) => {
//   let previousPage = 0 // تعریف متغیر سراسری برای نگهداری شماره صفحه قبلی

//   try {
//     const token = req.header('Authorization').split(' ')[1]
//     if (!token) return res.status(401).send('Access Denied')
//     const decodedToken = jwt.verify(token, process.env.APP_SECRET)

//     const { page = 1, limit = 10, province, city, category, search } = req.query
//     const currentPage = parseInt(page) // شماره صفحه جاری

//     const filter = {
//       payment_status: 'done',
//       status: 'accepted'
//     }
//     if (province) {
//       const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
//       filter.province = provinceFind
//     }
//     if (city) {
//       const cityFind = await CityModel.findOne({ id: city })
//       filter.city = cityFind
//     }
//     if (category) {
//       filter.category = category
//     }
//     if (search) {
//       filter.$or = [
//         { title: { $regex: search, $options: 'i' } },
//         { category: { $regex: search, $options: 'i' } }
//       ]
//     }
//     const options = {
//       page: parseInt(page),
//       limit: parseInt(limit),
//       sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt
//     }
//     const advertisings = await AdvertisingModel.paginate(filter, options)

//     // اگر شماره صفحه تغییر کرده بود، تعداد بازدیدها را به روز رسانی کنید
//     if (currentPage !== previousPage) {
//       await AdvertisingModel.updateMany(
//         { _id: { $in: advertisings.docs.map(ad => ad._id) } },
//         { $inc: { viewCount: 1 } }
//       )
//       previousPage = currentPage // به‌روزرسانی شماره صفحه قبلی
//     }
//     // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات
//     const advertisingIds = advertisings.docs.map(ad => ad._id)
//     const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } })

//     const creatorIds = advertisings.docs.map(ad => ad.creator_id)
//     const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } })
//     const newAds = advertisings.docs.map(ad => {
//       const creator = creators.find(user => user.user.toString() === ad.creator_id.toString())
//       const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id)
//       return {
//         // فیلدهای مشخص‌شده از ad._doc
//         _id: ad._doc._id,
//         category: ad._doc.category,
//         title: ad._doc.title,
//         province: ad._doc.province,
//         city: ad._doc.city,
//         neighbourhood: ad._doc.neighbourhood,
//         type: ad._doc.type,
//         mostDiscountPercentage: ad._doc.mostDiscountPercentage,
//         images: ad._doc.images,
//         likedByUser,
//         likesCount: ad._doc.likesCount,
//         commentsCount: ad._doc.commentsCount,
//         showDiscount: ad._doc.showDiscount,
//         viewCount: ad._doc.viewCount,
//         rate: {
//           adTotalRatings: creator?.adTotalRatings,
//           adAverageRating: creator?.adAverageRating
//         }
//       }
//     })
//     res.status(200).json({
//       advertisings: newAds,
//       totalPages: advertisings.totalPages,
//       totalItems: advertisings.totalDocs
//     })
//   } catch (error) {
//     next(error)
//   }
// }
const getAdvertisings = async (req, res, next) => {
  let previousPage = 0 // تعریف متغیر سراسری برای نگهداری شماره صفحه قبلی

  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    const decodedToken = jwt.verify(token, process.env.APP_SECRET)

    const { page = 1, limit = 10, province, city, category, search, sort } = req.query
    const currentPage = parseInt(page) // شماره صفحه جاری

    const filter = {
      payment_status: 'done',
      status: 'accepted'
    }
    if (province) {
      const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
      filter.province = provinceFind
    }
    if (city) {
      const cityFind = await CityModel.findOne({ id: city })
      filter.city = cityFind
    }
    if (category) {
      filter.category = category
    }
    if (search) {
      filter.$or = [
        { title: { $regex: search, $options: 'i' } },
        { category: { $regex: search, $options: 'i' } }
      ]
    }

    // مرتب‌سازی بر اساس پارامتر sort
    let sortOptions = { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی پیش‌فرض
    if (sort) {
      const sortFields = sort.split(',')
      sortFields.forEach(field => {
        if (field === 'mostDiscount') {
          sortOptions = { mostDiscountPercentage: -1 }
        } else if (field === 'highestRating') {
          sortOptions = { 'rate.adAverageRating': -1 }
        }
      })
    }

    const options = {
      page: parseInt(page),
      limit: parseInt(limit),
      sort: sortOptions // استفاده از مرتب‌سازی تنظیم‌شده
    }
    const advertisings = await AdvertisingModel.paginate(filter, options)

    // اگر شماره صفحه تغییر کرده بود، تعداد بازدیدها را به روز رسانی کنید
    if (currentPage !== previousPage) {
      await AdvertisingModel.updateMany(
        { _id: { $in: advertisings.docs.map(ad => ad._id) } },
        { $inc: { viewCount: 1 } }
      )
      previousPage = currentPage // به‌روزرسانی شماره صفحه قبلی
    }
    // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات
    const advertisingIds = advertisings.docs.map(ad => ad._id)
    const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } })

    const creatorIds = advertisings.docs.map(ad => ad.creator_id)
    const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } })
    const newAds = advertisings.docs.map(ad => {
      const creator = creators.find(user => user.user.toString() === ad.creator_id.toString())
      const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id)
      return {
        // فیلدهای مشخص‌شده از ad._doc
        _id: ad._doc._id,
        category: ad._doc.category,
        title: ad._doc.title,
        province: ad._doc.province,
        city: ad._doc.city,
        neighbourhood: ad._doc.neighbourhood,
        type: ad._doc.type,
        mostDiscountPercentage: ad._doc.mostDiscountPercentage,
        images: ad._doc.images,
        likedByUser,
        likesCount: ad._doc.likesCount,
        commentsCount: ad._doc.commentsCount,
        showDiscount: ad._doc.showDiscount,
        viewCount: ad._doc.viewCount,
        rate: {
          adTotalRatings: creator?.adTotalRatings,
          adAverageRating: creator?.adAverageRating
        }
      }
    })
    res.status(200).json({
      advertisings: newAds,
      totalPages: advertisings.totalPages,
      totalItems: advertisings.totalDocs
    })
  } catch (error) {
    next(error)
  }
}

const getAdvertisingsWeb = async (req, res, next) => {
  let previousPage = 0
  let userId = null

  try {
    const token = req.header('Authorization')
    if (token) {
      try {
        const decodedToken = jwt.verify(token.split(' ')[1], process.env.APP_SECRET)
        userId = decodedToken.id
      } catch (err) {
        console.warn('Invalid token:', err.message)
      }
    }

    const { page = 1, limit = 10, province, city, category, search, sort } = req.query
    const currentPage = parseInt(page)

    const filter = {
      // payment_status: 'done',
      status: 'accepted'
    }
    if (province) {
      const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
      filter.province = provinceFind
    }
    if (city) {
      const cityFind = await CityModel.findOne({ id: city })
      filter.city = cityFind
    }
    if (category) {
      filter.category = category
    }
    if (search) {
      filter.$or = [
        { title: { $regex: search, $options: 'i' } },
        { category: { $regex: search, $options: 'i' } }
      ]
    }

    let sortOptions = { acceptedAt: -1, createdAt: -1 }
    if (sort) {
      const sortFields = sort.split(',')
      sortFields.forEach(field => {
        if (field === 'mostDiscount') {
          sortOptions = { mostDiscountPercentage: -1 }
        } else if (field === 'highestRating') {
          sortOptions = { 'rate.adAverageRating': -1 }
        }
      })
    }

    const options = {
      page: parseInt(page),
      limit: parseInt(limit),
      sort: sortOptions
    }
    const advertisings = await AdvertisingModel.paginate(filter, options)

    if (currentPage !== previousPage) {
      await AdvertisingModel.updateMany(
        { _id: { $in: advertisings.docs.map(ad => ad._id) } },
        { $inc: { viewCount: 1 } }
      )
      previousPage = currentPage
    }

    const advertisingIds = advertisings.docs.map(ad => ad._id)
    const creatorIds = advertisings.docs.map(ad => ad.creator_id)
    const creators = await AdvertisingProfileModel.find({ user: { $in: creatorIds } })

    let advertisingLikes = []
    if (userId) {
      advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds }, userId })
    }

    const newAds = advertisings.docs.map(ad => {
      const creator = creators.find(user => user.user.toString() === ad.creator_id.toString())
      const likedByUser = userId ? advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString()) : false

      return {
        _id: ad._doc._id,
        category: ad._doc.category,
        title: ad._doc.title,
        province: ad._doc.province,
        city: ad._doc.city,
        neighbourhood: ad._doc.neighbourhood,
        type: ad._doc.type,
        mostDiscountPercentage: ad._doc.mostDiscountPercentage,
        images: ad._doc.images,
        likedByUser,
        likesCount: ad._doc.likesCount,
        commentsCount: ad._doc.commentsCount,
        showDiscount: ad._doc.showDiscount,
        viewCount: ad._doc.viewCount,
        rate: {
          adTotalRatings: creator?.adTotalRatings,
          adAverageRating: creator?.adAverageRating
        }
      }
    })

    res.status(200).json({
      advertisings: newAds,
      totalPages: advertisings.totalPages,
      totalItems: advertisings.totalDocs
    })
  } catch (error) {
    next(error)
  }
}

const getSingleAdvertising = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id

    const advertisingId = req.params.advertisingId
    const advertising = await AdvertisingModel.findById(advertisingId)
      .populate('creator_id', '_id user_name first_name last_name')

    if (!advertising) {
      return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' })
    }

    // دریافت تعداد لایک‌ها و بررسی اینکه آیا کاربر ویترین را لایک کرده است یا خیر
    const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId })
    const likedByUser = await AdvertisingLikeModel.findOne({ advertisingId, userId })

    // دریافت تعداد کامنت‌ها
    const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' })
    const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id })

    // اضافه کردن تعداد لایک‌ها، تعداد کامنت‌ها و وضعیت لایک به تبلیغ
    const advertisingData = {
      ...advertising._doc,
      likesCount,
      likedByUser: !!likedByUser,
      commentsCount,
      creatorId: creator?._id
    }

    res.status(200).json({
      advertising: advertisingData,
      rate: {
        adTotalRatings: creator?.adTotalRatings,
        adAverageRating: creator?.adAverageRating
      }
    })
  } catch (error) {
    next(error)
  }
}
const getSingleAdvertisingWeb = async (req, res, next) => {
  try {
    let userId = null
    let likedByUser = false

    // بررسی وجود توکن
    const authHeader = req.header('Authorization')
    if (authHeader) {
      const tokenParts = authHeader.split(' ')
      if (tokenParts.length === 2) {
        try {
          const decodedToken = jwt.verify(tokenParts[1], process.env.APP_SECRET)
          userId = decodedToken.id
        } catch (err) {
          console.error('Invalid Token:', err.message)
        }
      }
    }

    const advertisingId = req.params.advertisingId
    const advertising = await AdvertisingModel.findById(advertisingId)
      .populate('creator_id', '_id user_name first_name last_name')

    if (!advertising) {
      return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' })
    }

    // دریافت تعداد لایک‌ها
    const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId })

    // دریافت تعداد کامنت‌ها
    const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' })

    // دریافت اطلاعات سازنده تبلیغ
    const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id })

    // اگر کاربر احراز هویت شده باشد، وضعیت لایک‌شدن توسط او بررسی می‌شود
    if (userId) {
      likedByUser = !!(await AdvertisingLikeModel.findOne({ advertisingId, userId }))
    }

    // آماده‌سازی داده‌های تبلیغ
    const advertisingData = {
      ...advertising._doc,
      likesCount,
      likedByUser,
      commentsCount,
      creatorId: creator?._id
    }

    res.status(200).json({
      advertising: advertisingData,
      rate: {
        adTotalRatings: creator?.adTotalRatings,
        adAverageRating: creator?.adAverageRating
      }
    })
  } catch (error) {
    next(error)
  }
}

const getAdvertisingTypes = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    // const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    // const userId = decodedToken.id

    // const user = await UserModel.findById(userId)
    // if (!user) {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'کاربر یافت نشد'
    //   })
    // }
    // درخواست انواع تبلیغات از دیتابیس
    // let projectTypes = await AdvertisingTypeModel.find({}, 'name price')
    const advertisingTypes = await AdvertisingTypeModel.find({}, 'name price')

    // بررسی برای مواردی مانند پیدا نشدن انواع تبلیغات
    if (!advertisingTypes) {
      return res.status(404).json({ message: 'انواع تبلیغات یافت نشد.' })
    }
    // اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع تبلیغات رایگان را حذف کنید
    // if (user.daily_free_request <= 0) {
    //   advertisingTypes = advertisingTypes.filter(projectType => projectType.name !== 'free')
    // }
    // ارسال انواع تبلیغات به کاربر
    res.status(200).json({ advertisingTypes })
  } catch (error) {
    // در صورت بروز خطا، ارسال پیام خطا به کاربر
    console.error('Error in getAdvertisingTypes:', error)
    res.status(500).json({ message: 'خطا در دریافت انواع تبلیغات.' })
  }
}
const getAdvertisingCategory = async (req, res, next) => {
  try {
    // const token = req.header('Authorization').split(' ')[1]
    // if (!token) return res.status(401).send('Access Denied')
    // const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    // const userId = decodedToken.id

    // const user = await UserModel.findById(userId)
    // if (!user) {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'کاربر یافت نشد'
    //   })
    // }
    // let projectTypes = await AdvertisingTypeModel.find({}, 'name price')
    const categories = await AdvertisingCategoryModel.find({})

    // بررسی برای مواردی مانند پیدا نشدن انواع پروژه
    if (!categories) {
      return res.status(404).json({ message: 'دسته بندی یافت نشد.' })
    }
    // if (user.daily_free_request <= 0) {
    //   categories = categories.filter(projectType => projectType.name !== 'free')
    // }
    // ارسال انواع پروژه به کاربر
    res.status(200).json({ categories })
  } catch (error) {
    // در صورت بروز خطا، ارسال پیام خطا به کاربر
    console.error('Error in getAdvertisingTypes:', error)
    res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
  }
}

const getAdvertisingFeatures = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    // const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    // const userId = decodedToken.id

    // const user = await UserModel.findById(userId)
    // if (!user) {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'کاربر یافت نشد'
    //   })
    // }
    // let projectTypes = await AdvertisingTypeModel.find({}, 'name price')
    const features = await AdvertisingFeaturesModel.find({})

    // بررسی برای مواردی مانند پیدا نشدن امکانات
    if (!features) {
      return res.status(404).json({ message: 'امکانات یافت نشد.' })
    }
    // if (user.daily_free_request <= 0) {
    //   features = features.filter(projectType => projectType.name !== 'free')
    // }
    // ارسال امکانات به کاربر
    res.status(200).json({ features })
  } catch (error) {
    // در صورت بروز خطا، ارسال پیام خطا به کاربر
    console.error('Error in getAdvertisingTypes:', error)
    res.status(500).json({ message: 'خطا در دریافت امکانات.' })
  }
}
const toggleLike = async (req, res, next) => {
  try {
    const { advertisingId } = req.body
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    // بررسی وجود تبلیغات با استفاده از advertisingId
    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' })
    }
    // بررسی وضعیت لایک کردن توسط کاربر
    const isLiked = await AdvertisingLikeModel.findOne({ advertisingId, userId })
    if (isLiked) {
      // حذف لایک
      await AdvertisingLikeModel.findOneAndDelete({ advertisingId, userId })
      // کاهش تعداد لایک‌ها در تبلیغات
      advertising.likesCount -= 1
      await advertising.save()
      return res.status(200).json({ message: 'لایک با موفقیت پاک شد' })
    } else {
      // اضافه کردن لایک
      await AdvertisingLikeModel.create({ advertisingId, userId })
      // افزایش تعداد لایک‌ها در تبلیغات
      advertising.likesCount += 1
      await advertising.save()
      return res.status(201).json({ message: 'ویترین با موفقیت لایک شد' })
    }
  } catch (error) {
    next(error)
  }
}
const addComment = async (req, res, next) => {
  try {
    const { advertisingId, text } = req.body
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    // eslint-disable-next-line no-unused-vars
    const user = await UserModel.findById(decodedToken.id)
    // if (user.is_verified !== 'verified') {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'مدارک شما تایید نشده است'
    //   })
    // }
    const newComment = new AdvertisingComment({
      advertisingId,
      userId,
      text
    })

    await newComment.save()
    // افزایش تعداد کامنت‌های تبلیغ
    // await AdvertisingModel.findByIdAndUpdate(advertisingId, { $inc: { commentsCount: 1 } })

    res.status(201).json({ message: 'کامنت با موفقیت اضافه شد', comment: newComment })
  } catch (error) {
    next(error)
  }
}
const getComments = async (req, res, next) => {
  try {
    const { advertisingId, page = 1, limit = 10 } = req.query
    const options = {
      page: parseInt(page),
      limit: parseInt(limit),
      sort: { createdAt: -1 },
      populate: [{ path: 'userId', select: '_id profile_image user_type user_name first_name last_name is_verified' }]
    }

    const comments = await AdvertisingComment.paginate({ advertisingId, status: 'accepted' }, options)
    res.status(200).json({
      comments: comments.docs,
      totalPages: comments.totalPages,
      totalItems: comments.totalDocs
    })
  } catch (error) {
    next(error)
  }
}
const rateAdvertising = async (req, res, next) => {
  try {
    const { advertisingId, rating } = req.body
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id

    if (rating < 1 || rating > 5) {
      return res.status(400).json({ message: 'امتیاز باید بین 1 تا 5 باشد' })
    }

    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' })
    }

    const existingRating = await AdvertisingRatingModel.findOne({ advertisingId, userId })
    if (existingRating) {
      return res.status(400).json({ message: 'شما قبلا برای این ویترین امتیاز ثبت کرده‌اید' })
    } else {
      const newRating = new AdvertisingRatingModel({
        advertisingId,
        userId,
        rating
      })
      await newRating.save()
    }

    // به‌روزرسانی امتیازات کلی کاربر
    const advertisingProfile = await AdvertisingProfileModel.findOne({ user: advertising.creator_id })
    if (advertisingProfile) {
      const totalUserRatings = await AdvertisingRatingModel.aggregate([
        {
          $lookup: {
            from: 'advertisings',
            localField: 'advertisingId',
            foreignField: '_id',
            as: 'advertising'
          }
        },
        { $unwind: '$advertising' },
        { $match: { 'advertising.creator_id': advertising.creator_id } },
        { $group: { _id: null, total: { $sum: '$rating' }, count: { $sum: 1 } } }
      ])

      if (totalUserRatings.length > 0) {
        const { total, count } = totalUserRatings[0]
        advertisingProfile.adTotalRatings = total
        advertisingProfile.adRatingsCount = count
        advertisingProfile.adAverageRating = (total / count).toFixed(1)
      } else {
        advertisingProfile.adTotalRatings = 0
        advertisingProfile.adRatingsCount = 0
        advertisingProfile.adAverageRating = 0
      }

      await advertisingProfile.save()
    } else {
      // ایجاد پروفایل تبلیغاتی جدید در صورت عدم وجود
      const newAdvertisingProfile = new AdvertisingProfileModel({
        user: advertising.creator_id,
        adTotalRatings: rating,
        adRatingsCount: 1,
        adAverageRating: rating.toFixed(1)
      })
      await newAdvertisingProfile.save()
    }

    res.status(200).json({ message: 'امتیاز با موفقیت ثبت شد' })
  } catch (error) {
    next(error)
  }
}
const getUserAdvertisings = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id

    const { page = 1, limit = 10, status, search } = req.query

    const filter = {
      creator_id: userId
    }

    if (status) {
      filter.status = status
    }
    if (search) {
      filter.$or = [
        { title: { $regex: search, $options: 'i' } },
        { category: { $regex: search, $options: 'i' } }
      ]
    }

    const options = {
      page: parseInt(page),
      limit: parseInt(limit),
      sort: { updatedAt: -1 }
    }

    const advertisings = await AdvertisingModel.paginate(filter, options)

    // دریافت لیست لایک هر ویترین و اضافه کردن آن به اطلاعات تبلیغات
    const advertisingIds = advertisings.docs.map(ad => ad._id)
    const advertisingLikes = await AdvertisingLikeModel.find({ advertisingId: { $in: advertisingIds } })
    const creator = await AdvertisingProfileModel.findOne({ user: userId })

    const newAds = advertisings.docs.map(ad => {
      const likedByUser = advertisingLikes.some(like => like.advertisingId.toString() === ad._id.toString() && like.userId.toString() === decodedToken.id)
      let remainingTime = null
      if (ad.status === 'accepted' && ad.acceptedAt) {
        const expirationDate = new Date(ad.acceptedAt)
        expirationDate.setDate(expirationDate.getDate() + 15)
        const currentDate = new Date()
        const diffMilliseconds = expirationDate - currentDate
        const diffDays = Math.floor(diffMilliseconds / (1000 * 60 * 60 * 24))
        const diffHours = Math.floor((diffMilliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
        remainingTime = `${diffDays} روز و ${diffHours} ساعت`
      }
      return {
        _id: ad._doc._id,
        category: ad._doc.category,
        title: ad._doc.title,
        province: ad._doc.province,
        city: ad._doc.city,
        neighbourhood: ad._doc.neighbourhood,
        type: ad._doc.type,
        mostDiscountPercentage: ad._doc.mostDiscountPercentage,
        images: ad._doc.images,
        likedByUser,
        likesCount: ad._doc.likesCount,
        commentsCount: ad._doc.commentsCount,
        status: ad._doc.status,
        viewCount: ad._doc.viewCount,
        remainingTime,
        rate: {
          adTotalRatings: creator?.adTotalRatings,
          adAverageRating: creator?.adAverageRating
        }
      }
    })

    res.status(200).json({
      advertisings: newAds,
      totalPages: advertisings.totalPages,
      totalItems: advertisings.totalDocs
    })
  } catch (error) {
    next(error)
  }
}
const getUserSingleAdvertising = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    const user = await UserModel.findById(userId)
    if (!user) {
      return res.status(422).json({
        error: true,
        message: 'شما دسترسی به این بخش ندارید'
      })
    }
    const advertisingId = req.params.advertisingId
    const advertising = await AdvertisingModel.findById(advertisingId)
      .populate('creator_id', '_id user_name first_name last_name')

    if (!advertising) {
      return res.status(404).json({ message: 'ویترین مورد نظر یافت نشد' })
    }

    // دریافت تعداد لایک‌ها و بررسی اینکه آیا کاربر ویترین را لایک کرده است یا خیر
    const likesCount = await AdvertisingLikeModel.countDocuments({ advertisingId })
    const likedByUser = await AdvertisingLikeModel.findOne({ advertisingId, userId })

    // دریافت تعداد کامنت‌ها
    const commentsCount = await AdvertisingComment.countDocuments({ advertisingId, status: 'accepted' })
    const creator = await AdvertisingProfileModel.findOne({ user: advertising.creator_id._id })

    // اضافه کردن تعداد لایک‌ها، تعداد کامنت‌ها و وضعیت لایک به تبلیغ
    const advertisingData = {
      ...advertising._doc,
      likesCount,
      likedByUser: !!likedByUser,
      commentsCount,
      creatorId: creator?._id

    }

    res.status(200).json({
      advertising: advertisingData,
      rate: {
        adTotalRatings: creator?.adTotalRatings,
        adAverageRating: creator?.adAverageRating
      }
    })
  } catch (error) {
    next(error)
  }
}
const editAdvertising = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const user = await UserModel.findById(decodedToken.id)
    if (!user) {
      return res.status(422).json({
        error: true,
        message: 'شما دسترسی به این بخش ندارید'
      })
    }
    // if (user.is_verified !== 'verified') {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'مدارک شما تایید نشده است'
    //   })
    // }

    const errors = validationResult(req)
    if (!errors.isEmpty()) {
      return res.status(422).json({ errors: errors.array() })
    }

    const { id } = req.params
    const {
      category,
      title,
      description,
      province,
      city,
      neighbourhood,
      address,
      lat,
      lng,
      services,
      features,
      contactInfo,
      mostDiscountPercentage,
      showDiscount,
      type
    } = req.body

    if (!title || !category || !province || !city) {
      return res.status(422).json({
        error: true,
        message: 'اطلاعات ارسالی اشتباه است'
      })
    }

    const advertising = await AdvertisingModel.findOne({
      _id: id,
      creator_id: user._id,
      status: { $in: ['pre_payment', 'paid', 'rejected', 'expired'] }
    })

    if (!advertising) {
      return res.status(404).json({
        error: true,
        message: 'تبلیغ مورد نظر یافت نشد یا شما اجازه ویرایش آن را ندارید'
      })
    }

    const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
    const cityFind = await CityModel.findOne({ id: city })

    // مدیریت تصاویر برای خدمات
    const servicesWithImages = []
    const parsedServices = JSON.parse(services)
    if (parsedServices && parsedServices.length > 0) {
      for (const service of parsedServices) {
        if (typeof service.image === 'string' && service.image.startsWith('/services/')) {
          servicesWithImages.push(service)
        } else {
          const serviceImages = []
          const serviceId = service.id
          if (req.files && req.files.serviceImages && req.files.serviceImages[serviceId]) {
            const imageFiles = Array.isArray(req.files.serviceImages[serviceId]) ? req.files.serviceImages[serviceId] : [req.files.serviceImages[serviceId]]
            const uploadDir = path.join(__dirname, '../../../../storage/services')
            if (!fs.existsSync(uploadDir)) {
              fs.mkdirSync(uploadDir, { recursive: true })
            }
            for (const imageFile of imageFiles) {
              const uniqueFileName = `${user.user_name}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(imageFile.name)}`
              const filePath = path.join(uploadDir, uniqueFileName)
              await fs.move(imageFile.path, filePath)
              const imageUrl = `/services/${uniqueFileName}`
              serviceImages.push(imageUrl)
              service.image = imageUrl
            }
          }
          servicesWithImages.push({ ...service, image: serviceImages[0] })
        }
      }
    }
    // مدیریت تصاویر
    const images = []

    // اضافه کردن تصاویر موجود
    if (Array.isArray(req.body.existingImages)) {
      req.body.existingImages.forEach(image => {
        if (typeof image === 'string' && image.startsWith('/advertising/')) {
          images.push(image)
        }
      })
    }

    // اضافه کردن تصاویر جدید
    if (req.files && req.files.images) {
      const imageFiles = Array.isArray(req.files.images) ? req.files.images : [req.files.images]
      const uploadDir = path.join(__dirname, '../../../../storage/advertising')
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true })
      }
      for (const imageFile of imageFiles) {
        // بررسی فرمت تصویر
        if (imageFile && typeof imageFile === 'object' && imageFile.path) {
          const uniqueFileName = `${user.user_name}-${Date.now()}${Math.random().toString().slice(2, 11)}${path.extname(imageFile.name)}`
          const filePath = path.join(uploadDir, uniqueFileName)
          await fs.move(imageFile.path, filePath)
          const imageUrl = `/advertising/${uniqueFileName}`
          images.push(imageUrl)
        }
      }
    }
    const parsedFeatures = JSON.parse(features)

    advertising.title = title
    advertising.category = category
    advertising.description = description
    advertising.province = provinceFind
    advertising.city = cityFind
    advertising.neighbourhood = neighbourhood
    advertising.address = address
    advertising.lat = lat
    advertising.lng = lng
    advertising.images = images
    advertising.services = servicesWithImages
    advertising.features = parsedFeatures
    advertising.contactInfo = contactInfo
    advertising.mostDiscountPercentage = mostDiscountPercentage
    advertising.showDiscount = showDiscount
    advertising.type = type

    await advertising.save()

    if (contactInfo && contactInfo.saveInfoForNextAds) {
      user.contactInfo = contactInfo
      await user.save()
    }
    res.status(200).json({
      message: 'ویترین با موفقیت ویرایش شد',
      id: advertising._id
    })
  } catch (error) {
    next(error)
  }
}
const getUserAdvertisingProfile = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    const vitrineId = req.query.vitrineId

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const user = await UserModel.findById(decodedToken.id)
    if (!user) {
      return res.status(422).json({
        error: true,
        message: 'شما دسترسی به این بخش ندارید'
      })
    }
    // if (user.is_verified !== 'verified') {
    //   return res.status(422).json({
    //     error: true,
    //     message: 'مدارک شما تایید نشده است'
    //   })
    // }

    // دریافت اطلاعات پروفایل تبلیغاتی کاربر
    const advertisingProfile = await AdvertisingProfileModel.findById(vitrineId)
    if (!advertisingProfile) {
      return res.status(404).json({
        error: true,
        message: 'پروفایل تبلیغاتی یافت نشد'
      })
    }

    // دریافت تبلیغات‌های کاربر
    const userAds = await AdvertisingModel.find({ creator_id: advertisingProfile?.user })

    // جمع‌آوری اطلاعات از تبلیغات‌ها
    let allImages = []
    let allServices = []
    let allFeatures = []
    let totalCommentsCount = 0
    let totalLikesCount = 0

    for (const ad of userAds) {
      allImages = allImages.concat(ad.images)
      allServices = allServices.concat(ad.services)
      allFeatures = allFeatures.concat(ad.features)
      totalCommentsCount += ad.commentsCount
      totalLikesCount += ad.likesCount
    }

    // حذف آیتم‌های null و تکراری از allFeatures
    const uniqueFeatures = []
    const featureTitles = new Set()
    for (const feature of allFeatures) {
      if (feature && !featureTitles.has(feature.title)) {
        uniqueFeatures.push(feature)
        featureTitles.add(feature.title)
      }
    }

    // آماده‌سازی اطلاعات نهایی
    const profileDetails = {
      _id: advertisingProfile._id,
      profile_image: advertisingProfile.profile_image,
      vitrine_name: advertisingProfile.vitrine_name,
      category: advertisingProfile.category,
      about_us: advertisingProfile.about_us,
      province: advertisingProfile.province,
      city: advertisingProfile.city,
      lat: advertisingProfile.lat,
      lng: advertisingProfile.lng,
      neighbourhood: advertisingProfile.neighbourhood,
      adTotalRatings: advertisingProfile.adTotalRatings,
      adRatingsCount: advertisingProfile.adRatingsCount,
      adAverageRating: advertisingProfile.adAverageRating,
      contactInfo: advertisingProfile.contactInfo,
      address: advertisingProfile.address,
      allImages: allImages?.reverse(),
      allServices,
      allFeatures: uniqueFeatures,
      totalCommentsCount,
      totalLikesCount,
      is_self: !!(advertisingProfile && advertisingProfile?.user == decodedToken.id)
    }

    // ارسال پاسخ به کاربر
    res.status(200).json({ profileDetails })
  } catch (error) {
    next(error)
  }
}
const getUserAdvertisingProfileWeb = async (req, res, next) => {
  try {
    let userId = null
    let isSelf = false

    // بررسی توکن (در صورت وجود)
    const authHeader = req.header('Authorization')
    if (authHeader) {
      const tokenParts = authHeader.split(' ')
      if (tokenParts.length === 2) {
        try {
          const decodedToken = jwt.verify(tokenParts[1], process.env.APP_SECRET)
          userId = decodedToken.id
        } catch (err) {
          console.error('Invalid Token:', err.message)
        }
      }
    }

    const vitrineId = req.query.vitrineId
    console.log(vitrineId)

    // دریافت اطلاعات پروفایل تبلیغاتی کاربر
    const advertisingProfile = await AdvertisingProfileModel.findById(vitrineId)
    if (!advertisingProfile) {
      return res.status(404).json({
        error: true,
        message: 'پروفایل تبلیغاتی یافت نشد'
      })
    }

    // دریافت تبلیغات‌های کاربر
    const userAds = await AdvertisingModel.find({ creator_id: advertisingProfile?.user })

    // جمع‌آوری اطلاعات از تبلیغات‌ها
    let allImages = []
    let allServices = []
    let allFeatures = []
    let totalCommentsCount = 0
    let totalLikesCount = 0

    for (const ad of userAds) {
      allImages = allImages.concat(ad.images)
      allServices = allServices.concat(ad.services)
      allFeatures = allFeatures.concat(ad.features)
      totalCommentsCount += ad.commentsCount
      totalLikesCount += ad.likesCount
    }

    // حذف آیتم‌های null و تکراری از allFeatures
    const uniqueFeatures = []
    const featureTitles = new Set()
    for (const feature of allFeatures) {
      if (feature && !featureTitles.has(feature.title)) {
        uniqueFeatures.push(feature)
        featureTitles.add(feature.title)
      }
    }

    // بررسی اینکه کاربر خودش صاحب این ویترین است یا نه
    if (userId) {
      isSelf = advertisingProfile?.user == userId
    }

    // آماده‌سازی اطلاعات نهایی
    const profileDetails = {
      _id: advertisingProfile._id,
      profile_image: advertisingProfile.profile_image,
      vitrine_name: advertisingProfile.vitrine_name,
      category: advertisingProfile.category,
      about_us: advertisingProfile.about_us,
      province: advertisingProfile.province,
      city: advertisingProfile.city,
      lat: advertisingProfile.lat,
      lng: advertisingProfile.lng,
      neighbourhood: advertisingProfile.neighbourhood,
      adTotalRatings: advertisingProfile.adTotalRatings,
      adRatingsCount: advertisingProfile.adRatingsCount,
      adAverageRating: advertisingProfile.adAverageRating,
      contactInfo: advertisingProfile.contactInfo,
      address: advertisingProfile.address,
      allImages: allImages?.reverse(),
      allServices,
      allFeatures: uniqueFeatures,
      totalCommentsCount,
      totalLikesCount,
      is_self: isSelf
    }

    // ارسال پاسخ به کاربر
    res.status(200).json({ profileDetails })
  } catch (error) {
    next(error)
  }
}

const updateUserAdvertisingProfile = async (req, res, next) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')

    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const user = await UserModel.findById(decodedToken.id)
    if (!user) {
      return res.status(422).json({
        error: true,
        message: 'شما دسترسی به این بخش ندارید'
      })
    }

    const advertisingProfile = await AdvertisingProfileModel.findOne({ user: decodedToken.id })
    if (!advertisingProfile) {
      return res.status(404).json({
        error: true,
        message: 'پروفایل تبلیغاتی یافت نشد'
      })
    }

    if (advertisingProfile.user.toString() !== decodedToken.id) {
      return res.status(403).json({
        error: true,
        message: 'شما اجازه ویرایش این پروفایل را ندارید'
      })
    }

    const { profile_image } = req.files
    const {
      // profile_image,
      vitrine_name,
      category,
      about_us,
      province,
      city,
      lat,
      lng,
      address,
      neighbourhood,
      contactInfo
    } = req.body

    const updateFields = {}
    const provinceFind = await ProvinceModel.findOne({ id: province }, { _id: 0 })
    const cityFind = await CityModel.findOne({ id: city })
    // if (profile_image !== undefined && profile_image !== null && !profile_image.startsWith('/profiles/')) {
    if (profile_image !== undefined && profile_image !== null) {
      const uploadDir = path.join(__dirname, '../../../../storage/profiles')
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir, { recursive: true })
      }
      const uniqueFileName = `${advertisingProfile?.vitrine_name}-${Date.now()}${path.extname(profile_image.name)}`
      const filePath = path.join(uploadDir, uniqueFileName)
      await fs.move(profile_image.path, filePath)
      updateFields.profile_image = `/profiles/${uniqueFileName}`
    }
    if (vitrine_name !== undefined) updateFields.vitrine_name = vitrine_name
    if (category !== undefined) updateFields.category = category
    if (about_us !== undefined) updateFields.about_us = about_us
    if (province !== undefined) updateFields.province = provinceFind
    if (city !== undefined) updateFields.city = cityFind
    if (lat !== undefined) updateFields.lat = lat
    if (lng !== undefined) updateFields.lng = lng
    if (address !== undefined) updateFields.address = address
    if (neighbourhood !== undefined) updateFields.neighbourhood = neighbourhood
    if (contactInfo !== undefined) updateFields.contactInfo = contactInfo

    const updatedProfile = await AdvertisingProfileModel.findByIdAndUpdate(
      advertisingProfile._id,
      { $set: updateFields },
      { new: true }
    )

    res.status(200).json({
      success: true,
      message: 'پروفایل با موفقیت به‌روزرسانی شد',
      updatedProfile
    })
  } catch (error) {
    next(error)
  }
}

module.exports = {
  createAdvertisingValidationRules,
  createAdvertising,
  getAdvertisingTypes,
  getAdvertisingCategory,
  getSingleAdvertising,
  getAdvertisingFeatures,
  getAdvertisings,
  toggleLike,
  addComment,
  getComments,
  rateAdvertising,
  getUserAdvertisings,
  editAdvertising,
  getUserSingleAdvertising,
  getUserAdvertisingProfile,
  updateUserAdvertisingProfile,
  getAdvertisingsWeb,
  getSingleAdvertisingWeb,
  getUserAdvertisingProfileWeb
}
