/* eslint-disable eqeqeq */
const axios = require('axios')
const TypeAndPriceModel = require('../../../models/TypeAndPriceModel')
const ProjectModel = require('../../../models/ProjectModel')
const PaymentModel = require('../../../models/PaymentModel')
const jwt = require('jsonwebtoken')
const RequestModel = require('../../../models/RequestModel')
const NotificationModel = require('../../../models/NotificationModel')
const UserModel = require('../../../models/UserModel')
const AdvertisingTypeModel = require('../../../models/AdvertisingTypeModel')
const AdvertisingModel = require('../../../models/AdvertisingModel')

const apiKey = process.env.MERCHENT_CODE // Replace with your ZarinPal API Key

// Function to get price based on item name from database
const getPriceFromDatabase = async (itemName) => {
  const item = await TypeAndPriceModel.findOne({ name: itemName })
  if (!item) {
    throw new Error('Item not found in database')
  }
  return item.price
}
const getAdvertisingPriceFromDatabase = async (itemName) => {
  const item = await AdvertisingTypeModel.findOne({ name: itemName })
  if (!item) {
    throw new Error('Item not found in database')
  }
  return item.price
}

// Controller function for initiating payment
const initiatePayment = async (req, res) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    // eslint-disable-next-line no-unused-vars
    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    const itemName = req.body.item_name // Get item name from request body
    const price = await getPriceFromDatabase(itemName) // Get price from database
    const projectId = req.body.projectId // Get project ID from request body
    // Save project ID for later use in callback URL
    req.session.projectId = projectId
    const item = await TypeAndPriceModel.findOne({ name: itemName })
    const user = await UserModel.findById(userId)

    if (item.name === 'free' && item.price === 0) {
      if (user.daily_free_request > 0) {
        user.daily_free_request -= 1
        await user.save()
        const project = await ProjectModel.findById(projectId)
        if (!project) {
          res.status(404).send('Project not found')
          return
        }
        project.payment_status = 'done' // Set project status to 'done'
        project.status = 'paid' // Set project status to 'done'
        await project.save()
        res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', projectId, type: 'free' })
      } else {
        res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' })
      }
    } else {
      const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
        MerchantID: apiKey,
        Amount: Number(price),
        Description: `پرداخت برای سفارش شماره ${projectId}`,
        CallbackURL: `${process.env.APP_URL}/projects/payment?projectId=${projectId}&itemName=${itemName}&userId=${userId}` // Assuming your backend URL for handling payment callback
      })

      const data = response.data
      if (data.Status === 100) {
        // Payment request was successful
        const authority = data.Authority // The payment authority (شناسه پرداخت)
        res.status(200).json({ authority })
      } else {
        // Payment request failed
        console.error('Error occurred while initiating payment:', data)
        res.status(500).json({ error: 'Error occurred while initiating payment' })
      }
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

// Controller function for handling payment callback from ZarinPal
const handlePaymentCallback = async (req, res) => {
  try {
    // console.log(req.query)
    // Extract payment status and authority from ZarinPal callback
    const status = req.query.Status
    const authority = req.query.Authority
    const projectId = req.query.projectId // Get project ID from session
    const itemName = req.query.itemName // Get project ID from session
    const userId = req.query.userId // Get project ID from session
    // Clear project ID from session
    // Query ZarinPal API to verify payment status
    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const price = await getPriceFromDatabase(itemName) // Get price from database
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: Number(price)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      const payment = new PaymentModel({
        amount: Number(price),
        status: 'successful',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        project_id: projectId,
        type: 'create',
        installment_step: null
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()

      // Payment verification is successful
      // Now, update project status to 'done' or desired status
      const project = await ProjectModel.findById(projectId)
      if (!project) {
        res.status(404).send('Project not found')
        return
      }
      project.payment_status = 'done' // Set project status to 'done'
      project.status = 'paid' // Set project status to 'done'
      await project.save()

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentSuccess'
          // Example data: { message: 'Payment successful' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentFailed'
          // Example data: { message: 'Payment canceled or failed' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }

      // Redirect to the callback URL with the project ID
      res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${price}&type=create`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: Number(price),
        status: 'failed',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        project_id: projectId,
        type: 'create'
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${price}&type=create`)
    }
  } catch (error) {
    // Error occurred while verifying payment
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}

// Bazaar
const handleSuccessfulPayment = async (req, res) => {
  try {
    const { projectId } = 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 project = await ProjectModel.findById(projectId)
    if (!project) {
      res.status(404).send('Project not found')
      return
    }

    const price = await getPriceFromDatabase(project.project_type)

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

    // Update the project status to 'done' or 'paid'
    project.payment_status = 'done'
    project.status = 'paid'
    await project.save()

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

    res.status(200).json({ message: 'Payment recorded successfully', projectId, price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
// Controller function for handling failed payment
const handleFailedPayment = async (req, res) => {
  try {
    const { projectId } = 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 project = await ProjectModel.findById(projectId)
    if (!project) {
      res.status(404).send('Project not found')
      return
    }

    const price = await getPriceFromDatabase(project.project_type)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: Number(price),
      status: 'failed',
      authority: '', // Add authority if available
      user_id: userId,
      project_id: projectId,
      type: 'create'
    })
    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', projectId, price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

const paymentRequestStepOne = async (req, res) => {
  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 projectId = req.body.projectId
    // Find the project
    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({ error: 'Project not found' })
    }

    // Get the final price from the request model
    const requestId = req.body.requestId
    const request = await RequestModel.findById(requestId)
    if (!request) {
      return res.status(404).json({ error: 'Request not found' })
    }
    const halfAmount = request.price / 2

    // Proceed with ZarinPal payment request
    const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
      MerchantID: apiKey,
      Amount: parseInt(halfAmount + halfAmount / 100 * 9),
      Description: `پرداخت برای سفارش شماره ${projectId}`,
      CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-one-callback?projectId=${projectId}&requestId=${requestId}&userId=${userId}` // Callback URL including requestId
    })

    const data = response.data
    if (data.Status === 100) {
      // Payment request was successful
      const authority = data.Authority // The payment authority
      res.status(200).json({ authority })
    } else {
      // Payment request failed
      console.error('Error occurred while initiating payment:', data)
      res.status(500).json({ error: 'Error occurred while initiating payment' })
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
const paymentRequestStepTwo = async (req, res) => {
  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 projectId = req.body.projectId
    const installmentNumber = req.body.installmentNumber
    // Find the project
    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({ error: 'Project not found' })
    }

    // Calculate the amount for the second installment (1/4 of the total price)
    const totalAmount = project.final_price
    const secondInstallmentAmount = totalAmount / 4
    // Proceed with ZarinPal payment request for the second installment
    const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
      MerchantID: apiKey,
      Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9),
      Description: `پرداخت برای سفارش شماره ${projectId}`,
      CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-two-callback?projectId=${projectId}&userId=${userId}&installmentNumber=${installmentNumber}` // Callback URL
    })

    const data = response.data
    if (data.Status === 100) {
      // Payment request was successful
      const authority = data.Authority // The payment authority
      res.status(200).json({ authority })
    } else {
      // Payment request failed
      console.error('Error occurred while initiating payment:', data)
      res.status(500).json({ error: 'Error occurred while initiating payment' })
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
const paymentRequestStepAll = async (req, res) => {
  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 projectId = req.body.projectId

    // Find the project
    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({ error: 'Project not found' })
    }

    // Calculate the amount for the second installment (1/4 of the total price)
    const totalAmount = project.final_price
    const secondInstallmentAmount = totalAmount / 2

    // Proceed with ZarinPal payment request for the second installment
    const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
      MerchantID: apiKey,
      Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9),
      Description: `پرداخت برای سفارش شماره ${projectId}`,
      CallbackURL: `${process.env.APP_URL}/projects/payment-request-step-all-callback?projectId=${projectId}&userId=${userId}` // Callback URL
    })

    const data = response.data
    if (data.Status === 100) {
      // Payment request was successful
      const authority = data.Authority // The payment authority
      res.status(200).json({ authority })
    } else {
      // Payment request failed
      console.error('Error occurred while initiating payment:', data)
      res.status(500).json({ error: 'Error occurred while initiating payment' })
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
const paymentRequestStepOneCallback = async (req, res) => {
  try {
    const status = req.query.Status
    const authority = req.query.Authority
    const projectId = req.query.projectId
    const requestId = req.query.requestId
    const userId = req.query.userId

    // Verify payment status with ZarinPal
    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const request = await RequestModel.findById(requestId)
    if (!request) {
      return res.status(404).json({ error: 'Request not found' })
    }
    const price = request.price / 2
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: parseInt(price + price / 100 * 9)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      // Payment verification is successful
      const payment = new PaymentModel({
        amount: price,
        status: 'successful',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment',
        installment_step: 1
      })
      await payment.save()
      // Update project's installment details

      // Update project status
      request.status = 'accepted'
      await request.save()
      const project = await ProjectModel.findById(projectId)
      if (!project) {
        return res.status(404).json({ error: 'Project not found' })
      }
      project.selected_user = request.user
      project.status = 'ongoing'
      project.installments.push({ installment_number: 1, amount: price, due_date: new Date() })
      project.final_price = request.price
      project.final_time = request.time
      await project.save()
      // Send notification to selected user
      const notification = new NotificationModel({
        user_id: request.user,
        project_post_id: projectId,
        type: 'request_accepted',
        title: 'انتخاب پیشنهاد',
        description: `کارفرما پیشنهاد کاری شما برای پروژه ${project.title} را پذیرفت.`
      })
      await notification.save()

      // Sms

      const userReciver = await UserModel.findById(request.user)

      const data = JSON.stringify({
        mobile: userReciver?.mobile,
        templateId: '302876',
        parameters: [
          { name: 'USER', value: userReciver?.first_name + ' ' + userReciver?.last_name },
          { name: 'PROJECT', value: project?.title }
        ]
      })

      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)
        })

      // End Sms

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }

      // Redirect to the callback URL with the project ID
      res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${price}&type=steps&requestId=${requestId}`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: price,
        status: 'failed',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment'
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${price}&type=steps&requestId=${requestId}`)
    }
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}

const paymentRequestStepTwoCallback = async (req, res) => {
  try {
    const status = req.query.Status
    const authority = req.query.Authority
    const projectId = req.query.projectId
    const userId = req.query.userId
    const installmentNumber = req.query.installmentNumber

    // Verify payment status with ZarinPal
    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({ error: 'Project not found' })
    }
    const totalAmount = project.final_price
    const secondInstallmentAmount = totalAmount / 4
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      // Payment verification is successful
      const payment = new PaymentModel({
        amount: secondInstallmentAmount,
        status: 'successful',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment',
        installment_step: installmentNumber == 2 ? 2 : 3

      })
      await payment.save()

      // Update project's installment details
      project.installments.push({ installment_number: 2, amount: secondInstallmentAmount, due_date: new Date() })
      await project.save()

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }
      let description
      // eslint-disable-next-line eqeqeq
      if (installmentNumber == 2) {
        description = 'پرداخت'
      } else {
        description = 'کارفرما کل مبلغ پروژه را پرداخت کرد.'
      }
      const notification = new NotificationModel({
        user_id: project.selected_user,
        project_post_id: projectId,
        type: 'payment_progress',
        title: description,
        description
      })
      await notification.save()
      // Redirect to the callback URL with the project ID
      res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: secondInstallmentAmount,
        status: 'failed',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment'
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`)
    }
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}
const paymentRequestStepAllCallback = async (req, res) => {
  try {
    const status = req.query.Status
    const authority = req.query.Authority
    const projectId = req.query.projectId
    const userId = req.query.userId

    // Verify payment status with ZarinPal
    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({ error: 'Project not found' })
    }
    const totalAmount = project.final_price
    const secondInstallmentAmount = totalAmount / 2
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: parseInt(secondInstallmentAmount + secondInstallmentAmount / 100 * 9)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      // Payment verification is successful
      const payment = new PaymentModel({
        amount: secondInstallmentAmount,
        status: 'successful',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment',
        installment_step: 'all'

      })
      await payment.save()

      // Update project's installment details
      project.installments.push({ installment_number: 2, amount: secondInstallmentAmount, due_date: new Date() })
      await project.save()
      const notification = new NotificationModel({
        user_id: project.selected_user,
        project_post_id: projectId,
        type: 'payment_progress',
        title: 'پرداخت',
        description: 'کارفرما کل مبلغ پروژه را پرداخت کرد.'
      })
      await notification.save()

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }

      // Redirect to the callback URL with the project ID
      res.redirect(`modstagram://SuccessPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: secondInstallmentAmount,
        status: 'failed',
        authority,
        user_id: userId,
        project_id: projectId,
        type: 'installment'
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${projectId}&price=${secondInstallmentAmount}&type=steps`)
    }
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}

const initiateAdvertisingPayment = async (req, res) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    // eslint-disable-next-line no-unused-vars
    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    const itemName = req.body.item_name // Get item name from request body
    const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database
    const advertisingId = req.body.advertisingId // Get project ID from request body
    const showDiscount = req.body.showDiscount

    // Save project ID for later use in callback URL
    req.session.advertisingId = advertisingId
    const item = await AdvertisingTypeModel.findOne({ name: itemName })
    const user = await UserModel.findById(userId)

    if (item.name === 'free' && item.price === 0) {
      if (user.daily_free_request > 0) {
        user.daily_free_request -= 1
        await user.save()
        const project = await ProjectModel.findById(advertisingId)
        if (!project) {
          res.status(404).send('Project not found')
          return
        }
        project.payment_status = 'done' // Set project status to 'done'
        project.status = 'paid' // Set project status to 'done'
        await project.save()
        res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' })
      } else {
        res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' })
      }
    } else {
      const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
        MerchantID: apiKey,
        Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price),
        Description: `پرداخت برای سفارش شماره ${advertisingId}`,
        CallbackURL: `${process.env.APP_URL}/advertising/payment?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback
      })
      const data = response.data
      if (data.Status === 100) {
        // Payment request was successful
        const authority = data.Authority // The payment authority (شناسه پرداخت)
        res.status(200).json({ authority })
      } else {
        // Payment request failed
        console.error('Error occurred while initiating payment:', data)
        res.status(500).json({ error: 'Error occurred while initiating payment' })
      }
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
const handleAdvertisingPaymentCallback = async (req, res) => {
  try {
    // console.log(req.query)
    // Extract payment status and authority from ZarinPal callback
    const status = req.query.Status
    const authority = req.query.Authority
    const advertisingId = req.query.advertisingId // Get project ID from session
    const itemName = req.query.itemName // Get project ID from session
    const userId = req.query.userId // Get project ID from session
    const showDiscount = req.query.showDiscount // Get project ID from session
    // Clear project ID from session
    // Query ZarinPal API to verify payment status

    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      const payment = new PaymentModel({
        amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price),
        status: 'successful',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        advertising_id: advertisingId,
        type: 'advertising',
        installment_step: null
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()

      // Payment verification is successful
      // Now, update project status to 'done' or desired status
      const advertising = await AdvertisingModel.findById(advertisingId)
      if (!advertising) {
        res.status(404).send('Advertising not found')
        return
      }
      advertising.payment_status = 'done' // Set advertising status to 'done'
      advertising.status = 'paid' // Set advertising status to 'done'
      await advertising.save()

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentSuccess'
          // Example data: { message: 'Payment successful' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentFailed'
          // Example data: { message: 'Payment canceled or failed' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }

      // Redirect to the callback URL with the advertising ID
      res.redirect(`modstagram://SuccessPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: showDiscount ? Number(price + 20000) : Number(price),
        status: 'failed',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        advertising_id: advertisingId,
        type: 'advertising'
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price)}&type=advertising&showDiscount=${showDiscount}`)
    }
  } catch (error) {
    // Error occurred while verifying payment
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}

// Controller function for handling successful advertising payment
const handleSuccessfulAdvertisingPayment = async (req, res) => {
  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
    const showDiscount = req.query.showDiscount // Get project ID from session

    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      res.status(404).send('Advertising not found')
      return
    }

    const price = await getAdvertisingPriceFromDatabase(advertising.type)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price),
      status: 'successful',
      authority: '', // Add authority if available
      user_id: userId,
      advertising_id: advertisingId,
      type: 'advertising',
      installment_step: null
    })
    await payment.save()

    // Update the advertising status to 'done' or 'paid'
    advertising.payment_status = 'done'
    advertising.status = 'paid'
    await advertising.save()

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

    res.status(200).json({ message: 'Payment recorded successfully', advertisingId, price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
// Controller function for handling failed advertising payment
const handleFailedAdvertisingPayment = async (req, res) => {
  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
    const showDiscount = req.query.showDiscount // Get project ID from session
    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      res.status(404).send('Advertising not found')
      return
    }

    const price = await getAdvertisingPriceFromDatabase(advertising.type)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: showDiscount === true || showDiscount === 'true' ? Number(price + 20000) : Number(price),
      status: 'failed',
      authority: '', // Add authority if available
      user_id: userId,
      advertising_id: advertisingId,
      type: 'advertising'
    })
    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', advertisingId, price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

const republishAdvertisingPayment = async (req, res) => {
  try {
    const token = req.header('Authorization').split(' ')[1]
    if (!token) return res.status(401).send('Access Denied')
    // eslint-disable-next-line no-unused-vars
    const decodedToken = jwt.verify(token, process.env.APP_SECRET)
    const userId = decodedToken.id
    const itemName = req.body.item_name // Get item name from request body
    const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database
    const advertisingId = req.body.advertisingId // Get project ID from request body
    const showDiscount = req.body.showDiscount
    // Save project ID for later use in callback URL
    req.session.advertisingId = advertisingId
    const item = await AdvertisingTypeModel.findOne({ name: itemName })
    const user = await UserModel.findById(userId)

    if (item.name === 'free' && item.price === 0) {
      if (user.daily_free_request > 0) {
        user.daily_free_request -= 1
        await user.save()
        const project = await ProjectModel.findById(advertisingId)
        if (!project) {
          res.status(404).send('Project not found')
          return
        }
        project.payment_status = 'done' // Set project status to 'done'
        project.status = 'paid' // Set project status to 'done'
        await project.save()
        res.status(200).json({ message: 'پروژه رایگان با موفقیت ایجاد شد', advertisingId, type: 'free' })
      } else {
        res.status(403).json({ message: 'شما قبلاً از درخواست رایگان امروز استفاده کرده‌اید.' })
      }
    } else {
      const response = await axios.post('https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json', {
        MerchantID: apiKey,
        Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100),
        Description: `پرداخت برای سفارش شماره ${advertisingId}`,
        CallbackURL: `${process.env.APP_URL}/advertising/republish-verify-payment?advertisingId=${advertisingId}&itemName=${itemName}&userId=${userId}&showDiscount=${showDiscount}` // Assuming your backend URL for handling payment callback
      })
      const data = response.data
      if (data.Status === 100) {
        // Payment request was successful
        const authority = data.Authority // The payment authority (شناسه پرداخت)
        res.status(200).json({ authority })
      } else {
        // Payment request failed
        console.error('Error occurred while initiating payment:', data)
        res.status(500).json({ error: 'Error occurred while initiating payment' })
      }
    }
  } catch (error) {
    // Error occurred while getting price from database or sending the request
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
const handleAdvertisingRepublishPaymentCallback = async (req, res) => {
  try {
    // console.log(req.query)
    // Extract payment status and authority from ZarinPal callback
    const status = req.query.Status
    const authority = req.query.Authority
    const advertisingId = req.query.advertisingId // Get project ID from session
    const itemName = req.query.itemName // Get project ID from session
    const userId = req.query.userId // Get project ID from session
    const showDiscount = req.query.showDiscount // Get project ID from session
    // Clear project ID from session
    // Query ZarinPal API to verify payment status
    const verificationUrl = 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    const price = await getAdvertisingPriceFromDatabase(itemName) // Get price from database
    const verificationResponse = await axios.post(verificationUrl, {
      MerchantID: apiKey,
      Authority: authority,
      Amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)
    })

    const verificationData = verificationResponse.data
    if (verificationData.Status === 100) {
      const payment = new PaymentModel({
        amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100),
        status: 'successful',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        advertising_id: advertisingId,
        type: 'advertising',
        installment_step: null
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()

      // Payment verification is successful
      // Now, update project status to 'done' or desired status
      const advertising = await AdvertisingModel.findById(advertisingId)
      if (!advertising) {
        res.status(404).send('Advertising not found')
        return
      }
      advertising.payment_status = 'done' // Set advertising status to 'done'
      advertising.status = 'accepted' // Set advertising status to 'done'
      advertising.acceptedAt = new Date()
      await advertising.save()

      // Send event based on payment status
      if ('eventEmitter' in req.app) {
        if (status === 'OK') {
          // Payment is successful
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentSuccess'
          // Example data: { message: 'Payment successful' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Payment successful' })
        } else {
          // Payment is canceled or failed
          // Emit an event to be listened to in the frontend
          // Example event name: 'paymentFailed'
          // Example data: { message: 'Payment canceled or failed' }
          // You can customize the event name and data as needed
          req.app.get('eventEmitter').emit('paymentFailed', { message: 'Payment canceled or failed' })
        }
      } else {
        console.error('Error: eventEmitter is not defined or not properly configured.')
      }

      // Redirect to the callback URL with the advertising ID
      res.redirect(`modstagram://SuccessPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`)
    } else {
      // Payment verification failed
      const payment = new PaymentModel({
        amount: showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100),
        status: 'failed',
        authority,
        user_id: userId, // فرضاً شما از نوع میان‌افزارهای مدیریت کاربر استفاده می‌کنید و اطلاعات کاربر را از طریق `req.user` در دسترس دارید
        advertising_id: advertisingId,
        type: 'advertising'
        // دیگر اطلاعات مورد نیاز برای ثبت پرداخت
      })
      await payment.save()
      res.redirect(`modstagram://FailedPay?projectId=${advertisingId}&price=${showDiscount === true || showDiscount === 'true' ? Number(((price + 20000) * 70) / 100) : Number(((price) * 70) / 100)}&type=advertising-republish&showDiscount=${showDiscount}`)
    }
  } catch (error) {
    // Error occurred while verifying payment
    console.error('Error occurred:', error)
    res.status(500).send('Internal server error')
  }
}
// Controller function for handling successful republish advertising payment
const handleSuccessfulAdvertisingRepublishPayment = async (req, res) => {
  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
    const showDiscount = req.query.showDiscount

    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      res.status(404).send('Advertising not found')
      return
    }

    const price = await getAdvertisingPriceFromDatabase(advertising.type)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: showDiscount === true || showDiscount === 'true' ? Number((price + 20000) * 0.7) : Number(price * 0.7),
      status: 'successful',
      authority: '', // Add authority if available
      user_id: userId,
      advertising_id: advertisingId,
      type: 'advertising-republish',
      installment_step: null
    })
    await payment.save()

    // Update the advertising status to 'done' or 'accepted'
    advertising.payment_status = 'done'
    advertising.status = 'accepted'
    advertising.acceptedAt = new Date()
    await advertising.save()

    // Emit a success event
    if ('eventEmitter' in req.app) {
      req.app.get('eventEmitter').emit('paymentSuccess', { message: 'Republish payment successful' })
    } else {
      console.error('Error: eventEmitter is not defined or not properly configured.')
    }

    res.status(200).json({ message: 'Republish payment recorded successfully', advertisingId, price })
  } catch (error) {
    console.error('Error occurred:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}
// Controller function for handling failed republish advertising payment
const handleFailedAdvertisingRepublishPayment = async (req, res) => {
  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
    const showDiscount = req.query.showDiscount

    const advertising = await AdvertisingModel.findById(advertisingId)
    if (!advertising) {
      res.status(404).send('Advertising not found')
      return
    }

    const price = await getAdvertisingPriceFromDatabase(advertising.type)

    // Create a new payment entry
    const payment = new PaymentModel({
      amount: showDiscount === true || showDiscount === 'true' ? Number((price + 20000) * 0.7) : Number(price * 0.7),
      status: 'failed',
      authority: '', // Add authority if available
      user_id: userId,
      advertising_id: advertisingId,
      type: 'advertising-republish'
    })
    await payment.save()

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

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

module.exports = {
  initiatePayment,
  handlePaymentCallback,
  paymentRequestStepOne,
  paymentRequestStepTwo,
  paymentRequestStepAll,
  paymentRequestStepOneCallback,
  paymentRequestStepTwoCallback,
  paymentRequestStepAllCallback,
  initiateAdvertisingPayment,
  handleAdvertisingPaymentCallback,
  republishAdvertisingPayment,
  handleAdvertisingRepublishPaymentCallback,
  handleSuccessfulPayment,
  handleFailedPayment,
  handleSuccessfulAdvertisingPayment,
  handleFailedAdvertisingPayment,
  handleSuccessfulAdvertisingRepublishPayment,
  handleFailedAdvertisingRepublishPayment
}
