package controllers

import play.api._
import play.api.i18n._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import play.api.data.validation.Constraints._
import forms._
import models._
import utils._
import beans._
import org.squeryl._
import org.squeryl.PrimitiveTypeMode._
import scala.collection.mutable.ArrayBuffer

object NotifyController extends Controller{

  var notifies :org.squeryl.Query[Notify] = null

  val notifyRegistForm = Form(
      mapping(
          "message" -> nonEmptyText,
          "users" -> mapping(
        		  "name" -> nonEmptyText
          )(UserForm.apply)(UserForm.unapply),
          "state" -> text,
          "atach" -> mapping(
              "grpName" -> text
           )(AtachForm.apply)(AtachForm.unapply)
      )(NotifyForm.apply)(NotifyForm.unapply)
  )
  
  def createNotify(partId:Long, notifyType: Long) = Action{ implicit request =>
    	Ok(views.html.createNotifyForm(notifyRegistForm, partId, notifyType))
  }
  
  def notifyRegistration(partId: Long, notifyType: Long) = Action(parse.multipartFormData) { implicit request =>
    notifyRegistForm.bindFromRequest.fold(
        formWithErrors => BadRequest(views.html.createNotifyForm(formWithErrors, partId, notifyType)),
//        formWithErrors => BadRequest(views.html.error(formWithErrors)),
        notify => {
          inTransaction {
            val announceUser = PartsListDb.users.where(u => u.name === notify.users.name).head
            val paramState = Integer.decode(notify.state)
            val newNotify = PartsListDb.notifies.insert(Notify(notify.message, notify.atach, announceUser.id, notifyType, partId, paramState))
            val uploadAtach = UploadAtach()
            request.body.file("atach").map { atach =>
                 uploadAtach.uploadAtach(atach, newNotify.atach.grpName, 0, newNotify.id, 0)
              }
            val targetPart = PartsListDb.parts.where(p => p.id === partId).head
            val users = targetPart.project.assign(targetPart.project.head).users
            val sendMail = SendMail(notifyType, announceUser.email, targetPart.id, notifyType, paramState.longValue())
            for(user <- users) {
              sendMail.sendMail(user.email)
            }
          Ok(views.html.issueresult(notifyType))
          }
        }
    )
  }

  def showNotify(id: Long, partId: Long, notifyType: Long, state: Long) = Action { implicit request =>
    inTransaction {
      val notify = PartsListDb.notifies.where(n => n.id === id).head
      val notifyForm = NotifyForm(notify.message, UserForm(notify.user.assign(notify.user.head).name), Messages("notify.state" + notify.state), null)
      Ok(views.html.showNotifyForm(notifyRegistForm.fill(notifyForm), id, partId, notifyType, state, notify))
    }
  }

  def updateState(id: Long, partId: Long, notifyType: Long, state: Long) = Action {
    inTransaction {
      val notify = PartsListDb.notifies.where(n => n.id === id).head
      notify.state = 1
      PartsListDb.notifies.update(notify)
      val notifyForm = NotifyForm(notify.message, UserForm(notify.user.assign(notify.user.head).name), Messages("notify.state" + notify.state), null)
      Ok(views.html.showNotifyForm(notifyRegistForm.fill(notifyForm),id, partId, notifyType, state, notify))
    }
  }
  
  def appendAtach(id: Long, partId: Long, notifyType: Long, state: Long) = Action(parse.multipartFormData) { implicit request =>
    notifyRegistForm.bindFromRequest.fold(
        formWithErrors => BadRequest(views.html.showNotifyForm(formWithErrors, id, partId, notifyType, state, null)), 
        notify => {
          inTransaction {
            val uploadAtach = UploadAtach()
            request.body.file("atach").map{ atach =>
                uploadAtach.uploadAtach(atach, notify.atach.grpName, 0, id, 0)
              }
            Redirect(routes.NotifyController.showNotify(id, partId, notifyType, state))
          }
        }
    )
  }
  
  def listRecursion(page: Int, partId: Long, notifyType: Long, state: Long) = Action { implicit request =>
    val notifyBuffer = ArrayBuffer[NotifyBean]()
    inTransaction {
      val row = Integer.decode(Messages("list.row"))
      val notifyPart = PartsListDb.parts.where(p => p.id === partId).head
      if(state==9) {
    	  notifies = PartsListDb.notifies.where(n => n.partId === partId and n.notifyType === notifyType)
       } else {
         notifies = PartsListDb.notifies.where(n => n.partId === partId and n.notifyType === notifyType and n.state === state)
       }
      for(notify <- notifies) {
    	  var i:Int =0
    	  notifyBuffer += NotifyBean(i, notify.message, notify.user.assign(notify.user.head).name, notify.id, Messages("notify.state" + notify.state), notify.atachs)
    	  for(reply <- notify.replies) {
    	    Recursion(reply, notifyBuffer, i)
    	  }
       }
      Ok(views.html.notifylist(notifyBuffer.drop(page*row).take(row), notifyBuffer.size, notifyPart.id, notifyPart.name, page, notifyType, state))
    }
  }
  
  def Recursion(reply: Reply, notifyBuffer: ArrayBuffer[NotifyBean], i: Int):Unit = {
    var level = i+1
    notifyBuffer += NotifyBean(level, reply.message, reply.user.assign(reply.user.head).name, reply.id, Messages("notify.state9"), reply.atachs)
    for( childReply <- reply.childReplies) {
      Recursion(childReply, notifyBuffer, level)
    }
  }
}