package dev.fyloz.trial.colorrecipesexplorer.rest

import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeGroupServiceImpl
import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeServiceImpl
import dev.fyloz.trial.colorrecipesexplorer.model.*
import org.springframework.context.annotation.Profile
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.security.Principal
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

private const val EMPLOYEE_CONTROLLER_PATH = "api/employee"
private const val EMPLOYEE_GROUP_CONTROLLER_PATH = "api/employee/group"

@RestController
@RequestMapping(EMPLOYEE_CONTROLLER_PATH)
@Profile("rest")
class EmployeeController(employeeService: EmployeeServiceImpl) :
        AbstractRestModelApiController<Employee, EmployeeSaveDto, EmployeeUpdateDto, EmployeeServiceImpl>(employeeService, EMPLOYEE_CONTROLLER_PATH) {
    @GetMapping("current")
    @ResponseStatus(HttpStatus.OK)
    fun getCurrent(loggedInEmployee: Principal): ResponseEntity<Employee> = ResponseEntity.ok(service.getById(loggedInEmployee.name.toLong(), ignoreDefaultGroupUsers = false, ignoreSystemUsers = false))

    @PutMapping("{id}/password", consumes = [MediaType.TEXT_PLAIN_VALUE])
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun updatePassword(@PathVariable id: Long, @RequestBody password: String): ResponseEntity<Void> {
        service.updatePassword(id, password)
        return ResponseEntity
                .noContent()
                .build()
    }

    @PutMapping("{employeeId}/permissions/{permission}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun addPermission(@PathVariable employeeId: Long, @PathVariable permission: EmployeePermission): ResponseEntity<Void> {
        service.addPermission(employeeId, permission)
        return ResponseEntity
                .noContent()
                .build()
    }

    @DeleteMapping("{employeeId}/permissions/{permission}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun removePermission(@PathVariable employeeId: Long, @PathVariable permission: EmployeePermission): ResponseEntity<Void> {
        service.removePermission(employeeId, permission)
        return ResponseEntity
                .noContent()
                .build()
    }

    @GetMapping("logout")
    @ResponseStatus(HttpStatus.OK)
    fun logout(request: HttpServletRequest): ResponseEntity<Void> {
        service.logout(request)
        return ResponseEntity.ok().build()
    }
}

@RestController
@RequestMapping(EMPLOYEE_GROUP_CONTROLLER_PATH)
@Profile("rest")
class GroupsController(groupService: EmployeeGroupServiceImpl) :
        AbstractRestModelApiController<EmployeeGroup, EmployeeGroupSaveDto, EmployeeGroupUpdateDto, EmployeeGroupServiceImpl>(groupService, EMPLOYEE_GROUP_CONTROLLER_PATH) {
    @GetMapping("{id}/employees")
    @ResponseStatus(HttpStatus.OK)
    fun getEmployeesForGroup(@PathVariable id: Long): ResponseEntity<Collection<Employee>> = ResponseEntity.ok(service.getEmployeesForGroup(id))

    @PostMapping("default/{groupId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun setDefaultGroup(@PathVariable groupId: Long, response: HttpServletResponse): ResponseEntity<Void> {
        service.setResponseDefaultGroup(groupId, response)
        return ResponseEntity
                .noContent()
                .build()
    }

    @GetMapping("default")
    @ResponseStatus(HttpStatus.OK)
    fun getRequestDefaultGroup(request: HttpServletRequest): ResponseEntity<EmployeeGroup> =
            ResponseEntity.ok(service.getRequestDefaultGroup(request))

    @PutMapping("{groupId}/{employeeId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun addEmployeeToGroup(@PathVariable groupId: Long, @PathVariable employeeId: Long): ResponseEntity<Void> {
        service.addEmployeeToGroup(groupId, employeeId)
        return ResponseEntity
                .noContent()
                .build()
    }

    @DeleteMapping("{groupId}/{employeeId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    fun removeEmployeeFromGroup(@PathVariable groupId: Long, @PathVariable employeeId: Long): ResponseEntity<Void> {
        service.removeEmployeeFromGroup(groupId, employeeId)
        return ResponseEntity
                .noContent()
                .build()
    }
}
