package com.bytesw.bytebot.controller;


import com.bytesw.bytebot.bean.BusinessParameterBean;
import com.bytesw.bytebot.bean.BusinessParameterValueBean;
import com.bytesw.bytebot.bean.BusinessParameterConfigurationBean;
import com.bytesw.bytebot.service.BusinessParameterService;
import com.bytesw.xdf.annotation.ProgramSecurity;
import com.bytesw.xdf.controller.XDFController;
import com.bytesw.xdf.exception.ReferentialIntegrityException;
import com.bytesw.xdf.sql.beans.Pagination;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigInteger;
import java.time.OffsetDateTime;
import java.util.List;


@RestController()
@RequestMapping("/service/settings/business-parameter")
@ProgramSecurity("BUSINESS-PARAMETERS")
@Log4j2
public class BusinessParameterController extends XDFController<BusinessParameterBean, BigInteger> {
    @Autowired BusinessParameterService service;

    @Autowired
    protected GsonBuilder gsonBuilder;

    public BusinessParameterController(BusinessParameterService service) {
        super(service);
    }

    @RequestMapping(value = {"/value/{key}"}, method = {RequestMethod.PUT})
    @ApiResponses({
            @ApiResponse(code = 200, message = "Success", response = ResponseEntity.class),
            @ApiResponse(code = 404,message = "Not Found"),
            @ApiResponse(code = 409,message = "Already exists"),
            @ApiResponse(code = 505, message = "Internal Server Error")
    })
    @PreAuthorize("hasPermission(this, 'edit')")
    public ResponseEntity<Void> addNewAddValue(
            @ApiParam(value = "key", required = true) @PathVariable("key") String key,
            @ApiParam(value = "value", required = true) @RequestParam("value") String value,
            @ApiParam(value = "from", required = false) @RequestParam("from") String fromString) {

        OffsetDateTime from = OffsetDateTime.parse(fromString);

        this.service.addValue(key, value, from);
        return new ResponseEntity(HttpStatus.OK);
    }

    @RequestMapping(value = {"/create"}, method = {RequestMethod.POST})
    @ApiResponses({
            @ApiResponse(code = 200, message = "Success", response = ResponseEntity.class),
            @ApiResponse(code = 409, message = "Already Exists"),
            @ApiResponse(code = 505, message = "Internal Server Error")
    })
    @PreAuthorize("hasPermission(this, 'new')")
    public ResponseEntity<String> createWithValue(@RequestBody BusinessParameterValueBean bean, HttpServletRequest req) {
        Gson gson = gsonBuilder.create();
        bean = this.service.createWithValue(bean);
        return new ResponseEntity(gson.toJson(bean), HttpStatus.OK);
    }

    @RequestMapping(value = {"/current/{key}"}, method = {RequestMethod.GET})
    @ApiResponses({
            @ApiResponse(code = 200, message = "Success", response = ResponseEntity.class),
            @ApiResponse(code = 404,message = "Not Found"),
            @ApiResponse(code = 409, message = "Already Exists"),
            @ApiResponse(code = 505, message = "Internal Server Error")
    })
    @PreAuthorize("hasPermission(this, 'new')")
    public ResponseEntity<String> getCurrentValue(@ApiParam(value = "key", required = true) @PathVariable("key") String key) {
        Gson gson = gsonBuilder.create();
//        String value = this.service.getCurrentValue(key);
        String value = this.service.getCurrentValueParameterByKey(key);
        return new ResponseEntity(gson.toJson(value), HttpStatus.OK);
    }

    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @RequestMapping(
            method = {RequestMethod.GET},
            value = {"/parameter-value/{key}"}
    )
    @ResponseBody
    @PreAuthorize("hasPermission(this, 'view')")
    public ResponseEntity<String> getFeaturesTemplate(@PathVariable("key") String key) {
        String featuresTemplate = ((BusinessParameterService)this.service).getCurrentValueParameterByKey(key);
        return new ResponseEntity(this.gson.toJson(featuresTemplate), HttpStatus.OK);
    }

    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @RequestMapping(
            method = {RequestMethod.POST},
            value = {"/page"}
    )
    @ResponseBody
    @Override
    @PreAuthorize("hasPermission(this, 'view')")
    public ResponseEntity<String> findAllByPagination(@RequestBody Pagination<BusinessParameterBean> pagination) {
        if (pagination.getFilterExpression()!=null) {
            if (pagination.getFilterExpression().contains("(required==Y)")) {
                pagination.setFilterExpression(pagination.getFilterExpression().replace("(required==Y)", "(required==true)"));
            }
        }
        this.service.searchByPagination(pagination);
        return new ResponseEntity(this.gson.toJson(pagination), HttpStatus.OK);
    }

    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 404,
            message = "Not Found"
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @RequestMapping(
            value = {"/{id}"},
            method = {RequestMethod.DELETE}
    )
    @PreAuthorize("hasPermission(this, 'delete')")
    public ResponseEntity<String> delete(@PathVariable("id") BigInteger id, HttpServletRequest req) {
        this.service.delete(id);
        return new ResponseEntity(HttpStatus.OK);
    }

    @RequestMapping(
            value = {"/{id}"},
            method = {RequestMethod.PUT}
    )
    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 404,
            message = "Not Found"
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @PreAuthorize("hasPermission(this, 'edit')")
    public ResponseEntity<String> update(@PathVariable("id") BigInteger id, @RequestBody BusinessParameterBean bean, HttpServletRequest req) {
        try {
            if (this.service.validateKey(bean)) {
                throw new ReferentialIntegrityException("Ya existe un identificador con el mismo nombre");
            } else {
                this.service.update(bean, id);
            }
        } catch (ObjectOptimisticLockingFailureException var6) {
            BusinessParameterBean actualBean = this.service.getById(id);
            return new ResponseEntity(this.gson.toJson(actualBean), HttpStatus.CONFLICT);
        }

        return new ResponseEntity(HttpStatus.OK);
    }

    @RequestMapping(
            value = {"/"},
            method = {RequestMethod.POST}
    )
    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 409,
            message = "Already Exists"
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @PreAuthorize("hasPermission(this, 'new')")
    public ResponseEntity<String> create(@RequestBody BusinessParameterBean bean, HttpServletRequest req) {
        if (this.service.validateKey(bean)) {
            throw new ReferentialIntegrityException("Ya existe un identificador con el mismo nombre");
        } else {
            bean = this.service.createBP(bean);
            return new ResponseEntity(this.gson.toJson(bean), HttpStatus.OK);
        }
    }

    @ApiResponses({@ApiResponse(
            code = 200,
            message = "Success",
            response = ResponseEntity.class
    ), @ApiResponse(
            code = 404,
            message = "Not Found"
    ), @ApiResponse(
            code = 505,
            message = "Internal Server Error"
    )})
    @RequestMapping(
            value = {"/searchKey/{busnessKey}"},
            method = {RequestMethod.GET}
    )
    @PreAuthorize("hasPermission(this, 'showHistory')")
    public ResponseEntity<String> findByKey(@PathVariable("busnessKey") BigInteger busnessKey, HttpServletRequest req) {
        List<BusinessParameterConfigurationBean> bean = this.service.getConfigurationParametersList(busnessKey);
        return new ResponseEntity(this.gson.toJson(bean), HttpStatus.OK);
    }
}
