package cz.muni.fi.pa165.electricityTarifMicroservice.electricityprices;

import cz.muni.fi.pa165.electricityTarifMicroservice.electricityprices.dtos.ElectricityPriceGetFullDto;
import cz.muni.fi.pa165.electricityTarifMicroservice.electricityprices.dtos.ElectricityPricePostDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.DeleteMapping;
import java.util.List;

@Slf4j
@RestController
@RequestMapping(value = "/api/electricityprices", produces = MediaType.APPLICATION_JSON_VALUE)
@Tag(name = "ElectricityTarif", description = "Electricity tarif API")
public class ElectricityPriceController {
  private final ElectricityPriceServiceImpl electricityPriceService;

  @Autowired
  public ElectricityPriceController(ElectricityPriceServiceImpl electricityPriceService) {
    this.electricityPriceService = electricityPriceService;
  }

  @ControllerAdvice
  static class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(NoElectricityPriceForCompanyException.class)
    public void handleBadRequest() {
      // Nothing to do
    }
  }

  @Operation(
          summary = "Get all electricity prices for all companies",
          description = "Returns a list of all exsisting electricity price objects from the database." +
                  "In case there are none, it returns an empty list.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Found all electricity prices",
                          content = {
                                  @Content(
                                          mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          })
          })
  @GetMapping
  public List<ElectricityPriceGetFullDto> getAllElectricityPrice() {
    return electricityPriceService.getAllElectricityPrice();
  }

  @Operation(
          summary = "Get electricity price for the company",
          description = "Searches an electricity price by provided company id in URL." +
                  "Returns a CZK/kWh price of electricity price object from the database if found." +
                  "Price returned dependents of the time of the day (peek or non-peek hours) and weekday/weekend" +
                  "Otherwise if company is not found, an exception is thrown.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Found the electricity price",
                          content = {
                                  @Content(
                                          mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          }),
                  @ApiResponse(
                          responseCode = "404",
                          description = "Invalid or non-exsisting company id supplied",
                          content = @Content)
          })
  @GetMapping(path = "/{companyId}")
  public double getElectricityPrice(@PathVariable("companyId") String companyId) {
    return electricityPriceService.getElectricityPrice(companyId);
  }

  @Operation(
          summary = "Set electricity price for the company",
          description = "Adds/Changes an electricity price for the provided company id" +
                  "request body contains the companyId, priceHighTariff, priceLowTariff" +
                  "Returns an electricity price object from the database after commiting the change." +
                  "In case company id not being found, new electricity price object is entered in the database." +
                  "Returns an electricity price for the newly created object.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Added/Updated electricity price of a company",
                          content = {
                                  @Content(mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          })
          })
  @PostMapping
  public ElectricityPrice setElectricityPrice(@Valid @RequestBody ElectricityPricePostDto req) {
    return electricityPriceService.setElectricityPrice(req);
  }

  @Operation(
          summary = "Delete electricity price for the company",
          description = "Searches an electricity price by provided company id in URL." +
                  "Deletes an electricity price object from the database if found." +
                  "Otherwise, returns a message about the error.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Deleted electricity price for a company",
                          content = {
                                  @Content(mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class)) }),
                  @ApiResponse(
                          responseCode = "404",
                          description = "Invalid or non-exsisting company id supplied",
                          content = @Content)
          })
  @DeleteMapping(path = "/{companyId}")
  public String deleteElectricityPriceForCompany(@PathVariable("companyId") String companyId) {
    return electricityPriceService.deleteElectricityPriceForCompany(companyId);
  }

  @Operation(
          summary = "Get all electricity prices for all companies per page",
          description = "Returns a list of all exsisting electricity price objects per page from the database." +
                  "In case there are none, it returns an empty list.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Found all electricity prices",
                          content = {
                                  @Content(
                                          mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          })
          })
  @GetMapping("/page")
  public Page<ElectricityPriceGetFullDto> getAllElectricityPricePageable(Pageable pageable) {
    return electricityPriceService.getAllElectricityPricePagable(pageable);
  }

  @Operation(
          summary = "Get average high tariff electricity price of all companies",
          description = "Returns average high tariff electricity price of all companies from the database.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Found average high tariff electricity price",
                          content = {
                                  @Content(
                                          mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          })
          })
  @GetMapping("/avg/hightariff")
  public double getAveragePriceHighTariff() {
    return electricityPriceService.averagePriceHighTariff();
  }

  @Operation(
          summary = "Get average low tariff electricity price of all companies",
          description = "Returns average low tariff electricity price of all companies from the database.")
  @ApiResponses(
          value = {
                  @ApiResponse(
                          responseCode = "200",
                          description = "Found average low tariff electricity price",
                          content = {
                                  @Content(
                                          mediaType = "application/json",
                                          schema = @Schema(implementation = ElectricityPrice.class))
                          })
          })
  @GetMapping("/avg/lowtariff")
  public double getAveragePriceLowTariff() {
    return electricityPriceService.averagePriceLowTariff();
  }
}
