 mail = require '../commons/mail'
 MailSent = require '../mail/sent/MailSent'
+UserRemark = require '../users/remarks/UserRemark'
 User = require '../users/User'
 async = require 'async'
 errors = require '../commons/errors'

    
testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
  
### Candidate Update Reminder Task ###

candidateUpdateProfileTask = ->
  mailTaskName = "candidateUpdateProfileTask"

      sendwithus.api.send context, (err, result) ->
        log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err
        sendEmailCallback null
### End Approved Candidate Update Reminder Task ###
  
### Unapproved Candidate Finish Reminder Task ###
unapprovedCandidateFinishProfileTask = ->
  mailTaskName = "unapprovedCandidateFinishProfileTask"
  lockDurationMs = 2 * 60 * 1000
  currentDate = new Date()
  timeRanges = []
  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']]
    timeRanges.push
      start: generateWeekOffset currentDate, weekPair[0]
      end: generateWeekOffset currentDate, weekPair[1]
      name: weekPair[2]
  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
    async.each timeRanges, emailUnapprovedCandidateTimeRange.bind({mailTaskName: mailTaskName}), (err) ->
      if err
        log.error "There was an error sending the candidate profile update reminder emails: #{err}"
      else
        log.info "Completed mail task #{mailTaskName}"
      lockManager.releaseLock mailTaskName, (err) ->
        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"

emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) ->
  waterfallContext =
    "timeRange": timeRange
    "mailTaskName": @mailTaskName
  async.waterfall [
    findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext)
    (unfilteredCandidates, cb) ->
      async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null)
    (unfilteredPotentialCandidates, cb) ->
      async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null)
    (filteredCandidates, cb) ->
      async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb
  ], emailTimeRangeCallback

findAllUnapprovedCandidatesWithinTimeRange = (cb) ->
  findParameters =
    "jobProfile":
      $exists: true
    "jobProfile.updated":
      $gt: @timeRange.start
      $lte: @timeRange.end
    "jobProfileApproved": false
  selection =  "_id email jobProfile.name jobProfile.updated emails"
  User.find(findParameters).select(selection).lean().exec cb

ignoredCandidateFilter = (candidate, cb) ->
  findParameters = 
    "user": candidate._id
    "contactName": "Ignore"
  UserRemark.count findParameters, (err, results) ->
    if err? then return true
    return cb Boolean(results.length)
    
unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) ->
  if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
    return sentEmailFilterCallback true
  findParameters =
    "user": candidate._id
    "mailTask": @mailTaskName
    "metadata.timeRangeName": @timeRange.name
    "metadata.updated": candidate.jobProfile.updated
  MailSent.find(findParameters).lean().exec (err, sentMail) ->
    if err?
      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
      sentEmailFilterCallback true
    else
      sentEmailFilterCallback Boolean(sentMail.length)

sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) ->
  if err?
    log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}"
    return sendEmailCallback err
  context =
    email_id: "tem_RXyjzmc7S2HJH287pfoSPN"
    recipient:
      address: candidate.email
      name: candidate.jobProfile.name
    email_data:
      user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
      recipient_address: encodeURIComponent(candidate.email)
  log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})"
  newSentMail =
    mailTask: @mailTaskName
    user: candidate._id
    metadata:
      timeRangeName: @timeRange.name
      updated: candidate.jobProfile.updated
  MailSent.create newSentMail, (err) ->
    if err? then return sendEmailCallback err
    sendwithus.api.send context, (err, result) ->
      log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err
      sendEmailCallback null
### End Unapproved Candidate Finish Reminder Task ###
  
### Internal Candidate Update Reminder Email ###
internalCandidateUpdateTask = ->
  mailTaskName = "internalCandidateUpdateTask"
