/* eslint-disable camelcase */
const jwt = require('jsonwebtoken')
const jMoment = require('moment-jalaali')
const OfferModel = require('../../../models/OfferModel')
const UserModel = require('../../../models/UserModel')
const OfferTypeModel = require('../../../models/OfferTypeModel')
const PaymentModel = require('../../../models/PaymentModel')
const NotificationModel = require('../../../models/NotificationModel')
const { default: axios } = require('axios')
const CommentModel = require('../../../models/CommentModel')

const getOfferPriceFromDatabase = async (itemName) => {
  const item = await OfferTypeModel.findOne({ name: itemName })
  if (!item) {
    throw new Error('Item not found in database')
  }
  return item.price
}

const getOfferTypes = 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 offerTypes = await OfferTypeModel.find({}, 'name price')

    // بررسی برای مواردی مانند پیدا نشدن انواع پروژه
    if (!offerTypes) {
      return res.status(404).json({ message: 'انواع پروژه یافت نشد.' })
    }
    // اگر کاربر درخواست ماهانه  نداشته باشد، نوع پروژه ماهانه را حذف کنید
    if (user.monthly_free_offer <= 0) {
      offerTypes = offerTypes.filter(projectType => projectType.name !== 'free')
    }
    // ارسال انواع پروژه به کاربر
    res.status(200).json({ offerTypes })
  } catch (error) {
    // در صورت بروز خطا، ارسال پیام خطا به کاربر
    console.error('Error in getOfferTypes:', error)
    res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
  }
}
const getUserOffers = 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_filter, id } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست
    let filter = {}
    let filterbyid = {receiver: id}
    let filterbyidsender = {sender: id}
    if (status_filter === 'درخواست') {
      filter = { sender: userId }
    } else {
      filter = { receiver: userId }
    }

    // تنظیم گزینه‌های صفحه‌بندی
    const options = {
      page: parseInt(page), // تبدیل صفحه به عدد صحیح
      limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
      sort: { createdAt: -1 }, // بر اساس زمان ایجاد (createdAt) مرتب کنید (نزولی)
      populate: [
        {
          path: 'sender',
          select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
        },
        {
          path: 'receiver',
          select: 'profile_image user_level first_name last_name user_name is_verified user_score rate'
        }
      ]
    }

    // دریافت آفرهای صفحه‌بندی شده
    let offer = await OfferModel.paginate(filter, options)
    let offerbyid = await OfferModel.paginate(filterbyid, options)
    let offerbyidsender = await OfferModel.paginate(filterbyidsender, options)
    
    const totalPages = offer.totalPages
    const totalItems = offer.totalDocs

    // فرمت کردن تاریخ و ارسال پاسخ
    offer = offer?.docs.map(offer => {
      const jDate = jMoment(offer.createdAt).format('jYYYY-jMM-jDD HH:mm')
      return {
        ...offer._doc,
        createdAt: jDate
      }
    })
    res.json({
      offerbyidsender,
      offerbyid,
      offer,
      totalPages, // ارسال تعداد کل صفحات
      totalItems // ارسال تعداد کل آیتم‌ها
    })
  } catch (error) {
    next(error)
  }
}

const updateOfferStatus = 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 // ID کاربری که درخواست را به‌روزرسانی می‌کند
    const reciverUser = await UserModel.findById(userId)

    const { offerId, action } = req.body // آیدی آفر و اکشن (accept یا reject)

    // بررسی اعتبار ورودی‌ها
    if (!offerId || !['accept', 'reject'].includes(action)) {
      return res.status(400).json({ error: 'Invalid input' })
    }

    // یافتن آفر موردنظر
    const offer = await OfferModel.findById(offerId)
    const senderUser = await UserModel.findById(offer?.sender)

    if (!offer) {
      return res.status(404).json({ error: 'Offer not found' })
    }

    // بررسی اینکه آیا کاربر گیرنده این آفر است یا خیر
    if (offer.receiver.toString() !== userId) {
      return res.status(403).json({ error: 'You are not authorized to update this offer' })
    }

    // بررسی اینکه آیا آفر قبلاً به‌روزرسانی شده یا نه
    if (offer.status !== 'pending') {
      return res.status(400).json({ error: 'Offer has already been updated', message: 'وضعیت این درخواست قبلا تغییر کرده است.' })
    }

    // به‌روزرسانی وضعیت آفر بر اساس اکشن
    offer.status = action === 'accept' ? 'accepted' : 'rejected'
    await offer.save()

    if (action === 'accept') {
      const data = JSON.stringify({
        mobile: senderUser?.mobile,
        templateId: '633448',
        parameters: [
          { name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
          { name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
        ]
      })

      const config = {
        method: 'post',
        url: 'https://api.sms.ir/v1/send/verify',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'text/plain',
          'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
        },
        data
      }
      axios(config)
        .then(function (response) {
        })
        .catch(function (error) {
          console.log(error)
        })
    } else {
      const data = JSON.stringify({
        mobile: senderUser?.mobile,
        templateId: '682678',
        parameters: [
          { name: 'USER', value: reciverUser?.first_name + ' ' + reciverUser?.last_name },
          { name: 'EMPLOYER', value: senderUser?.first_name + ' ' + senderUser?.last_name }
        ]
      })

      const config = {
        method: 'post',
        url: 'https://api.sms.ir/v1/send/verify',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'text/plain',
          'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
        },
        data
      }
      axios(config)
        .then(function (response) {
        })
        .catch(function (error) {
          console.log(error)
        })
    }
    res.status(200).json({
      message: `Offer has been ${offer.status} successfully`,
      offerId: offer._id,
      status: offer.status
    })
  } catch (error) {
    next(error)
  }
}

// Controller function for handling successful advertising payment
const handleSuccessfulOfferPayment = async (req, res) => {
  try {
    const { reciverId, offerType } = 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

    // Check user's free offer eligibility
    const user = await UserModel.findById(userId)
    if (!user) return res.status(404).json({ error: 'User not found' })
    // Check user's free offer eligibility
    const reciverUser = await UserModel.findById(reciverId)
    if (!user) return res.status(404).json({ error: 'User not found' })

    let price
    if (user.monthly_free_offer > 0 && offerType === 'free') {
      // Use free offer and decrement counter
      price = 0
      user.monthly_free_offer -= 1
      await user.save()
    } else {
      // Retrieve offer price based on type
      price = await getOfferPriceFromDatabase(offerType)

      // Create a new payment entry
      const payment = new PaymentModel({
        amount: Number(price),
        status: 'successful',
        authority: '', // Add authority if available
        user_id: userId,
        type: 'offer',
        installment_step: null
      })
      await payment.save()
    }
    // Create a new payment entry
    const payment = new PaymentModel({
      amount: Number(price),
      status: 'successful',
      authority: '', // Add authority if available
      user_id: userId,
      type: 'offer',
      installment_step: null
    })
    await payment.save()

    // Create a new offer
    const offer = new OfferModel({
      sender: userId,
      receiver: reciverId,
      transaction_id: payment._id // Link the payment to the offer
    })
    await offer.save()
    console.log(reciverUser?.first_name)

    // Send notification to selected user
    const notification = new NotificationModel({
      user_id: reciverId,
      project_post_id: offer?._id,
      type: 'new_offer',
      title: 'درخواست همکاری جدید',
      description: `${reciverUser?.first_name} عزیز یک درخواست همکاری برای شما در مجموعه مدستاگرام ثبت شد`
    })
    await notification.save()

    // Send Sms
    const data = JSON.stringify({
      mobile: reciverUser?.mobile,
      templateId: '569006',
      parameters: [
        { name: 'FIRSTNAME', value: reciverUser?.first_name },
        { name: 'LASTNAME', value: reciverUser?.last_name }

      ]
    })

    const config = {
      method: 'post',
      url: 'https://api.sms.ir/v1/send/verify',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'text/plain',
        'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
      },
      data
    }
    axios(config)
      .then(function (response) {
      })
      .catch(function (error) {
        console.log(error)
      })

    // Send event based on payment status

    // Emit a success event
    if ('eventEmitter' in req.app) {
      req.app.get('eventEmitter').emit('paymentSuccess', {
        message: 'Payment and offer created successfully',
        offerId: offer._id
      })
    } else {
      console.error('Error: eventEmitter is not defined or not properly configured.')
    }

    res.status(200).json({
      message: 'Payment and offer recorded successfully',
      offerId: offer._id,
      price
    })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
// Controller function for handling failed advertising payment
const handleFailedOfferPayment = async (req, res) => {
  try {
    const { offerType } = 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

    const price = await getOfferPriceFromDatabase(offerType)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: Number(price),
      status: 'failed',
      authority: '', // Add authority if available
      user_id: userId,
      type: 'offer',
      installment_step: null
    })
    await payment.save()

    // Emit a failure event
    if ('eventEmitter' in req.app) {
      req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment failed' })
    } else {
      console.error('Error: eventEmitter is not defined or not properly configured.')
    }

    res.status(200).json({ message: 'Payment failed', price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

const createOfferComment = 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 { offerId, comment, rate, user_id } = req.body
    if (!offerId || !comment || !rate || !user_id) {
      return res.status(400).send({ message: 'All fields are required' })
    }
    // بررسی اینکه آیا کاربر قبلاً برای این پیشنهاد نظر داده است
    const existingComment = await CommentModel.findOne({
      offer: offerId,
      creator: userId
    })
    if (existingComment) {
      return res.status(400).send({ message: 'شما قبلاً نظر خود را برای این درخواست ثبت کرده‌اید' })
    }
    const newComment = new CommentModel({
      user: user_id,
      offer: offerId,
      creator: userId,
      rating: rate,
      comment,
      comment_for: 'user',
      status: 'pending'
    })
    await newComment.save()

    const user = await UserModel.findById(user_id)

    // پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل
    const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
    const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))

    let userLevel
    if (user.expertise === 'مدل') {
      if (totalRating <= 50) userLevel = 'تازه وارد'
      else if (totalRating <= 100) userLevel = 'استاندارد'
      else if (totalRating <= 300) userLevel = 'حرفه‌ای'
      else userLevel = 'استاد'
    } else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
      if (totalRating <= 50) userLevel = 'تازه وارد'
      else if (totalRating <= 100) userLevel = 'استاندارد'
      else if (totalRating <= 300) userLevel = 'حرفه‌ای'
      else userLevel = 'استاد'
    }

    user.user_score = totalRating
    user.user_level = userLevel

    const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
    const averageRating = totalRating / totalComments
    user.rate = averageRating.toFixed(1)
    await user.save()

    res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد' })
  } catch (error) {
    next(error)
  }
}

module.exports = {
  getUserOffers,
  getOfferTypes,
  handleSuccessfulOfferPayment,
  handleFailedOfferPayment,
  updateOfferStatus,
  createOfferComment
}
