import org.codehaus.groovy.grails.plugins.springsecurity.Secured

@Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_TaskManager', 'ROLE_TaskUser'])
class EntryDetailedController extends BaseController {

    def authService
    def taskService

    def index = { redirect(action:list,params:params) }

    // the delete, save and update actions only accept POST requests
    static allowedMethods = [delete:'POST', save:'POST', update:'POST']

    def list = {
        if(!params.max) params.max = 10
        [ entryInstanceList: Entry.list( params ) ]
    }

    def show = {
        def entryInstance = Entry.get( params.id )

        if(!entryInstance) {
            flash.message = "Entry not found with id ${params.id}"
            redirect(controller: 'taskDetailed', action: 'search')
        }
        else { return [ entryInstance : entryInstance ] }
    }

    def delete = {
        def entryInstance = Entry.get( params.id )
        if(entryInstance) {
            if(entryInstance.enteredBy.loginName == authService.currentUser.loginName) {
                def taskId = entryInstance.task.id
                entryInstance.delete(flush:true)
                flash.message = "Entry ${params.id} deleted"
                redirect(controller: 'taskDetailed', action: 'show', id: taskId)
            }
            else {
                flash.message = "You may only delete your own entries."
                redirect(action:show,id:entryInstance.id)
            }

        }
        else {
            flash.message = "Entry not found with id ${params.id}"
            redirect(controller: "taskDetailed", action:"search")
        }
    }

    def edit = {
        def entryInstance = Entry.get( params.id )
        if(!entryInstance) {
                flash.message = "Entry not found with id ${params.id}"
                redirect(controller: "taskDetailed", action:"search")
        }
        else {

            if(entryInstance.enteredBy.loginName == authService.currentUser.loginName) {
                return [ entryInstance : entryInstance ]
            }
            else {
                flash.message = "You may only edit your own entries."
                redirect(action:show,id:entryInstance.id)
            }

        }
    }

    /// @todo: Refactor to taskService and include moving task to "In Progress" when Entry.duration is updated.
    def update = {
        def entryInstance = Entry.get( params.id )
        if(entryInstance) {
            // The update method only accepts post requests, so this is just in case.
            if(entryInstance.enteredBy.loginName == authService.currentUser.loginName) {
                entryInstance.properties = params
                if(!entryInstance.hasErrors() && entryInstance.save(flush: true)) {
                    // If PM Entry update task.highestSeverity
                    if(entryInstance.entryType.id == 6) {
                        def clist = []
                        entryInstance.task.entries.each { entry ->
                            if(entry.entryType.id == 6)
                                clist << entry.highestSeverity
                        }

                        if(clist)
                            entryInstance.task.highestSeverity = clist.sort{p1,p2 -> p2.id <=> p1.id}[0]
                    }
                    flash.message = "Entry ${params.id} updated"
                    redirect(action:show,id:entryInstance.id)
                }
                else {
                    render(view:'edit',model:[entryInstance:entryInstance])
                }
            }
            else {
                flash.message = "You may only edit your own entries."
                redirect(action:show,id:entryInstance.id)
            }
        }
        else {
            flash.message = "Entry not found with id ${params.id}"
            redirect(controller: "taskDetailed", action:"search")
        }
    }

    def ajaxCreate = {
        if(!params.taskId || !params.entryTypeId) {
            response.status = 403
            params.errorMessage = g.message(code: "entry.create.no.params.ajax")
            render(template: "/shared/messages")
            return
        }

        def taskInstance = Task.read(params.taskId)

        if(!taskInstance) {
            response.status = 403
            params.errorMessage = g.message(code:"default.not.found", args:['Task',params.taskId])
            render(template: "/shared/messages")
            return
        }

        // Check for Complete task.
        if(taskInstance.taskStatus.id == 3) {
            response.status = 403
            params.errorMessage = g.message(code:"task.operationNotPermittedOnCompleteTask")
            render(template: "/shared/messages")
            return
        }

        // Success.
        def entryInstance = new Entry()
        entryInstance.task = taskInstance
        entryInstance.entryType = EntryType.read(params.entryTypeId)
        render(template: "create", model: ['entryInstance': entryInstance])
    }

    def ajaxSave = {
        def result = taskService.saveEntry(params)

        // Success.
        if(!result.error) {
            def entryList = Entry.withCriteria {
                                                                eq("entryType", result.entryInstance.entryType)
                                                                task {
                                                                    idEq(result.taskId)
                                                                }
                                                        }
            render(template: "list", model: ['entryList': entryList])
            return
        }

        if(result.error.code != "default.create.failure") {
            response.status = 403
            params.errorMessage = g.message(code: result.error.code)
            render(template: "/shared/messages")
            return
        }

        response.status = 403
        render(template: "create", model: ['entryInstance': result.entryInstance])
    } // ajaxSave

    def create = {
        if(!params.taskInstance?.id || !params.entryType?.id) {
            flash.message = g.message(code:"entry.create.no.params")
            redirect(controller:"taskDetailed", action:"search")
            return
        }

        def taskInstance = Task.read(params.taskInstance.id)

        if(!taskInstance) {
            flash.message = g.message(code:"task.notFound")
            redirect(controller:"taskDetailed", action:"search")
            return
        }

        // Check for Complete task.
        if(taskInstance.taskStatus.id == 3) {
            flash.errorMessage = g.message(code:"task.operationNotPermittedOnCompleteTask")
            redirect(controller:"taskDetailed", action:"show", id: taskInstance.id)
            return
        }

        def entryInstance = new Entry()
        entryInstance.task = taskInstance
        entryInstance.entryType = EntryType.read(params.entryType.id)
        return ['entryInstance': entryInstance]
    } // create

    def save = {
        def result = taskService.saveEntry(params)

        if(!result.error) {
            flash.message = "Entry created."
            redirect(controller: "taskDetailed", action: "show", id: result.taskId)
            return
        }

        if(result.error.code != "default.create.failure") {
            params.errorMessage = g.message(code: result.error.code)
        }

        render(view:'create',model:[entryInstance: result.entryInstance])
    } // save

} // end class
