package com.rera.mss.controller

import com.rera.mss.payload.*
import com.rera.mss.security.CurrentUser
import com.rera.mss.security.UserPrincipal
import com.rera.mss.service.InverterService
import com.rera.mss.service.InverterServiceOperationResult
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/inverters")
class InverterController(
        private val service: InverterService
) {

    @PostMapping()
    @PreAuthorize("hasRole('USER')")
    fun addInverter(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody inverter: InverterDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.addInverter(currentUser, inverter)) {
            is InverterServiceOperationResult.Success -> buildCreatedResponseEntity("/api/instrument/{guid}", result.value)
            is InverterServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Inverter could not have been created"), HttpStatus.BAD_REQUEST)
        }
    }

    @GetMapping()
    @PreAuthorize("hasRole('USER')")
    fun getInverters(
            @CurrentUser currentUser: UserPrincipal
    ): ResponseEntity<InverterListDto> {
        return when (val result = service.getInverters(currentUser)) {
            is InverterServiceOperationResult.Success -> ResponseEntity.ok().body(result.value)
            is InverterServiceOperationResult.Error -> ResponseEntity.badRequest().body(InverterListDto(inverters = emptySet(), availableMonitoredAreas = emptySet()))
        }
    }

    @PutMapping()
    @PreAuthorize("hasRole('USER')")
    fun updateInverter(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody inverter: InverterDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.updateInverter(currentUser, inverter)) {
            is InverterServiceOperationResult.Success -> ResponseEntity.ok(ApiResponse(true, "Inverter ${inverter.id} updated successfully"))
            is InverterServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Inverter could not have been created"), HttpStatus.BAD_REQUEST)
        }
    }

    private fun buildCreatedResponseEntity(path: String, inverter: InverterDto) = ResponseEntity
            .created(createLocation(path, inverter.id.toString()))
            .body(ApiResponse(success = true, message = "Inverter created successfully."))

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