InitiativeForNotification = mondelefant.new_class()
InitiativeForNotification.table = 'initiative_for_notification'

InitiativeForNotification:add_reference{
  mode          = 'm1',
  to            = "Initiative",
  this_key      = 'initiative_id',
  that_key      = 'id',
  ref           = 'initiative',
}


function InitiativeForNotification:notify_member_id(member_id)
  
  db:query("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ")
  
  local member = Member:by_id(member_id)

  locale.set{ lang = member.lang or config.default_lang }
 
  local selector = db:new_selector()
    :add_field("*")
    :from({ "get_initiatives_for_notification(?)", member_id }, "initiative_for_notification")
    :left_join("initiative", nil, "initiative.id = initiative_for_notification.initiative_id")
    :left_join("issue", nil, "issue.id = initiative.issue_id")
    :join("member", nil, "member.id = initiative_for_notification.recipient_id")
    :add_order_by("md5(initiative_for_notification.recipient_id || '-' || member.notification_counter || '-' || issue.area_id)")
    :add_order_by("md5(initiative_for_notification.recipient_id || '-' || member.notification_counter || '-' || issue.id)")

  selector._class = self

  local initiatives_for_notification = selector:exec()

  db:query("COMMIT")
  
  if not member.notify_email then
    return
  end
  
  if #initiatives_for_notification < 1 then
    return
  end
  
  io.stderr:write("Sending digest #" .. member.notification_counter .. " to " .. member.notify_email .. "\n")
  
  local initiatives = initiatives_for_notification:load("initiative")
  local issues = initiatives:load("issue")
  issues:load("area")
  issues:load("policy")

  local last_area_id
  local last_issue_id
  
  local draft_count = 0
  local suggestion_count = 0
  
  local draft_initiative
  local suggestion_initiative
  
  local ms = {}
  
  for i, entry in ipairs(initiatives_for_notification) do
    local initiative = entry.initiative
    local issue = initiative.issue
    local area = issue.area
    local policy = issue.policy
    
    local m = {}
    if last_area_id ~= area.id then
      m[#m+1] = "*** " .. area.name .. " ***"
      m[#m+1] = ""
      last_area_id = area.id
    end
    if last_issue_id ~= issue.id then
      local state_time_text
      if string.sub(issue.state_time_left, 1, 1) == "-" then
        state_time_text = _"Phase ends soon"
      else
        state_time_text = format.interval_text(issue.state_time_left, { mode = "time_left" })
      end
      m[#m+1] = "---"
      m[#m+1] = policy.name .. " #" .. issue.id .. " - " .. issue.state_name .. " - " .. state_time_text
      m[#m+1] = ""
      last_issue_id = issue.id
    end
    m[#m+1] = initiative.display_name
    local source
    if entry.supported then
      source = _"has my support"
      if entry.new_draft then
        source = source .. ", " .. _"draft updated"
        draft_count = draft_count + 1
        draft_initiative = initiative
      end
      if entry.new_suggestion_count then
        if entry.new_suggestion_count == 1 then
          source = source .. ", " .. _"new suggestion added"
        elseif entry.new_suggestion_count > 1 then
          source = source .. ", " .. _("#{count} suggestions added", { count = entry.new_suggestion_count })
        end
        suggestion_count = suggestion_count + entry.new_suggestion_count
        if suggestion_initiative and suggestion_initiative.id ~= initiative.id then
          suggestion_initiative = false
        elseif suggestion_initiative ~= false then
          suggestion_initiative = initiative
        end
      end
    elseif entry.featured then
      source = _"featured"
    end
    if entry.leading then
      source = source and source .. ", " or ""
      source = source .. _"currently leading"
    end
    m[#m+1] = "(" .. source .. ")"
    m[#m+1] = ""
    if not initiatives_for_notification[i+1] or initiatives_for_notification[i+1].issue_id ~= issue.id then
      m[#m+1] = _("more: #{url}", { url = request.get_absolute_baseurl() .. "issue/show/" .. issue.id .. ".html" })
      m[#m+1] = ""
    end
    ms[#ms+1] = table.concat(m, "\n")
  end

  local info = {}
    
  if draft_count > 0 then
    if draft_count == 1 then
      info[#info+1] = _"draft updated for " .. draft_initiative.display_name
    else
      info[#info+1] = _("drafts of #{draft_count} initiatives updated", { draft_count = draft_count })
    end
  end
  
  if suggestion_count > 0 then
    if suggestion_count == 1 then
      info[#info+1] = _"new suggestion for " .. suggestion_initiative.display_name
    elseif suggestion_initiative then
      info[#info+1] = _("#{count} suggestions added for #{initiative}", { count = suggestion_count, suggestion_initiative.display_name })
    else
      info[#info+1] = _("#{count} suggestions added", { count = suggestion_count })
    end
  end
  
  if draft_count == 0 and suggestion_count == 0 then
    info[#info+1] = _"featured initiatives"
  end
  
  local subject = _("Digest #{id}: #{info}", {
    id = member.notification_counter, info = table.concat(info, ", ")
  })
  
  local template = config.notification_digest_template
  
  local message = _(template, {
    name = member.name,
    digest = table.concat(ms, "\n")
  })
  
  local success = net.send_mail{
    envelope_from = config.mail_envelope_from,
    from          = config.mail_from,
    reply_to      = config.mail_reply_to,
    to            = { name = member.name, address = member.notify_email },
    subject       = subject,
    content_type  = "text/plain; charset=UTF-8",
    content       = message
  }

end

function InitiativeForNotification:notify_next_member()
  local scheduled_notification_to_send = ScheduledNotificationToSend:get_next()
  if not scheduled_notification_to_send then
    return false
  end
  InitiativeForNotification:notify_member_id(scheduled_notification_to_send.recipient_id)
  return true
end

