package com.rera.mss.controller

import com.rera.mss.payload.ApiResponse
import com.rera.mss.payload.MonitoredAreaDto
import com.rera.mss.payload.MonitoredAreaListDto
import com.rera.mss.security.CurrentUser
import com.rera.mss.security.UserPrincipal
import com.rera.mss.service.MonitoredAreaService
import com.rera.mss.service.MonitoredAreaServiceOperationResult
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.*
import org.springframework.web.servlet.support.ServletUriComponentsBuilder
import java.net.URI
import javax.validation.Valid

@RestController
@RequestMapping("/api/monitoredAreas")
class MonitoredAreaController(
        private val service: MonitoredAreaService
) {
    @PostMapping()
    @PreAuthorize("hasRole('USER')")
    fun addInstrument(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody monitoredArea: MonitoredAreaDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.addMonitoredArea(currentUser, monitoredArea)) {
            is MonitoredAreaServiceOperationResult.Success ->  buildCreatedResponseEntity("/api/instrument/{id}", result.value)
            is MonitoredAreaServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Monitored area could not have been created"), HttpStatus.BAD_REQUEST)
        }
    }

    @GetMapping()
    @PreAuthorize("hasRole('USER')")
    fun getMonitoredAreas(
            @CurrentUser currentUser: UserPrincipal
    ): ResponseEntity<MonitoredAreaListDto> {
        return when (val result = service.getMonitoredAreas(currentUser)) {
            is MonitoredAreaServiceOperationResult.Success -> ResponseEntity.ok().body(result.value)
            is MonitoredAreaServiceOperationResult.Error -> ResponseEntity.badRequest().body(MonitoredAreaListDto(monitoredAreas = emptySet(), availablePvPanels = emptySet()))
        }
    }

    @PutMapping()
    @PreAuthorize("hasRole('USER')")
    fun updateInstrument(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody monitoredArea: MonitoredAreaDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.updateMonitoredArea(currentUser, monitoredArea)) {
            is MonitoredAreaServiceOperationResult.Success -> ResponseEntity.ok(ApiResponse(true, "Monitored area ${monitoredArea.id} updated successfully"))
            is MonitoredAreaServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Monitored area could not have been updated"), HttpStatus.BAD_REQUEST)
        }
    }

    private fun buildCreatedResponseEntity(path: String, ma: MonitoredAreaDto) = ResponseEntity
            .created(createLocation(path, ma.id))
            .body(ApiResponse(success = true, message = "Monitored area created successfully."))

    private fun createLocation(path: String, id: Long): URI = ServletUriComponentsBuilder
            .fromCurrentContextPath()
            .path(path)
            .buildAndExpand(id)
            .toUri()
}