/* eslint-disable camelcase */
const ProjectModel = require('../../../models/ProjectModel')
const jwt = require('jsonwebtoken')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const NotificationModel = require('../../../models/NotificationModel')
const CommentModel = require('../../../models/CommentModel')

const doneProject = 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 { project_id, comment, rate, user_id } = req.body
    if (!project_id || !comment || !rate || !user_id) {
      return res.status(400).send({ message: 'All fields are required' })
    }

    const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
    if (!project) {
      return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
    }

    const getTotalPaidAmount = (installments) => {
      return installments.reduce((total, installment) => total + installment.amount, 0)
    }

    const getRemainingAmount = (project) => {
      const totalPaidAmount = getTotalPaidAmount(project.installments)
      return project.final_price - totalPaidAmount
    }

    const remainingAmount = getRemainingAmount(project)
    if (remainingAmount !== 0) {
      return res.status(422).send({ message: 'مبلغ کامل پرداخت نشده است' })
    }

    project.status = 'done'
    await project.save()

    const newComment = new CommentModel({
      user: user_id,
      project: project_id,
      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()

    const notification = new NotificationModel({
      user_id: user._id,
      project_post_id: project_id,
      type: 'end_project',
      title: 'اتمام پروژه',
      description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
      `
    })
    await notification.save()

    res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
  } catch (error) {
    next(error)
  }
}
const doneProjectWeb = 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 { project_id, comment, rate, user_id } = req.body
    if (!project_id || !comment || !rate || !user_id) {
      return res.status(400).send({ message: 'All fields are required' })
    }

    const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
    if (!project) {
      return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
    }

    project.status = 'done'
    await project.save()

    const newComment = new CommentModel({
      user: user_id,
      project: project_id,
      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()

    const notification = new NotificationModel({
      user_id: user._id,
      project_post_id: project_id,
      type: 'end_project',
      title: 'اتمام پروژه',
      description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
      `
    })
    await notification.save()

    res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
  } catch (error) {
    next(error)
  }
}

const cancleProject = 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 { project_id, comment, rate, user_id } = req.body

    if (!project_id || !comment || !rate || !user_id) {
      return res.status(400).send({ message: 'All fields are required' })
    }

    const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
    if (!project) {
      return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
    }

    project.status = 'cancled'
    await project.save()

    const newComment = new CommentModel({
      user: user_id,
      project: project_id,
      creator: userId,
      rating: rate,
      comment,
      comment_for: 'project',
      status: 'pending'
    })
    await newComment.save()

    res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
  } catch (error) {
    next(error)
  }
}

const editProjectValidationRules = () => {
  return [
    check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),

    check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'),

    check('gender')
      .isIn(['male', 'female'])
      .withMessage('جنسیت باید male یا female باشد'),

    check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'),

    check('conversation_projects')
      .notEmpty()
      .withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد')
      .isBoolean()
      .withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'),

    check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),

    check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'),

    check('offer_time')
      .notEmpty()
      .withMessage('زمان پروژه نمی‌تواند خالی باشد'),

    check('offer_price')
      .notEmpty()
      .withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'),

    check('description')
      .notEmpty()
      .withMessage('توضیحات نمی‌تواند خالی باشد')
  ]
}

const editProject = 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 {
      title,
      expertise,
      sub_expertise,
      gender,
      age,
      conversation_projects,
      province,
      city,
      offer_time,
      offer_price,
      description,
      projectId
    } = req.body

    const project = await ProjectModel.findById(projectId)
    if (!project) {
      return res.status(404).json({
        error: true,
        message: 'پروژه مورد نظر یافت نشد'
      })
    }
    // eslint-disable-next-line eqeqeq
    if (user._id.toString() != project.creator_id.toString()) {
      return res.status(422).json({
        error: true,
        message: 'شما نمیتوانید این پروژه را ویرایش کنید'
      })
    }
    if (project.status !== 'paid' && project.status !== 'pre_payment') {
      return res.status(422).json({
        error: true,
        message: 'شما نمیتوانید این پروژه را ویرایش کنید'
      })
    }
    // اعتبارسنجی اطلاعات ویرایش شده
    if (
      !title ||
      !expertise ||
      !age ||
      conversation_projects === null ||
      !province ||
      !city ||
      !offer_time ||
      !offer_price ||
      !description
    ) {
      return res.status(422).json({
        error: true,
        message: 'اطلاعات ارسالی اشتباه است'
      })
    }
    const provinceFind = await ProvinceModel.findOne(
      { id: province },
      { _id: 0 }
    )
    const cityFind = await CityModel.findOne({ id: city })
    // ویرایش یک نسخه از پروژه
    project.title = title
    project.expertise = expertise
    project.sub_expertise = sub_expertise
    project.gender = gender
    project.age = age
    project.conversation_projects = conversation_projects
    project.province = provinceFind
    project.city = cityFind
    project.offer_time = offer_time
    project.offer_price = offer_price
    project.description = description
    // ذخیره کردن تغییرات در پایگاه داده
    await project.save()
    res.status(200).json({
      message: 'پروژه با موفقیت ویرایش شد',
      id: project._id
    })
  } catch (error) {
    next(error)
  }
}
const setRateProject = 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 { project_id, comment, rate } = req.body
    const project = await ProjectModel.findOne({ _id: project_id, selected_user: userId })
    if (!project) {
      return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
    }
    project.ratings.push({
      project_id,
      rating: rate,
      comment,
      creator_id: userId
    })
    await project.save()

    res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد.' })
  } catch (error) {
    next(error)
  }
}
module.exports = {
  doneProject, cancleProject, editProject, editProjectValidationRules, setRateProject, doneProjectWeb
}
