package io.delphiplatform.api.v3.view;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;

import io.delphiplatform.api.v3.constant.ApplicationConstants;
import io.delphiplatform.api.v3.model.SortOrder;
import io.delphiplatform.api.v3.model.gras.Companies;
import io.delphiplatform.api.v3.model.gras.Company;
import io.delphiplatform.api.v3.view.util.Params;

@Validated
public interface CompaniesApi {

    /**
     * GET /companies/{company_id} : Get one Company Resource route for getting a single &#x60;Company&#x60;.
     *
     * @param companyKey Primary key identifier for a &#x60;Company&#x60;. (required)
     * @return &#x60;Company&#x60; response object (status code 200) or A &#x60;400 Bad Request&#x60; response status
     * indicates a problem with the input provided by a client request. If you are receiving this error, check your
     * request parameters are valid.  (status code 400) or A &#x60;401 Unauthorized&#x60; response status indicates that
     * the request did not include a required Authorization header, or that there was a problem authenticating the
     * client. Possible problems include an expired or invalid token, or the Authorization header is not in the expected
     * format.  (status code 401) or A &#x60;404 Not Found&#x60; response status is returned when a single item queried
     * by primary key identifier was not found in the database, or an endpoint path was provided that does not exist.
     * (status code 404) or A &#x60;500 Internal Error&#x60; response status is returned for any application and server
     * level errors that are not already associated with another error status. A 500 is used as a generic fallback
     * error.  (status code 500)
     */
    @RequestMapping(value = "/companies/{company_key}",
        produces = {"application/json"},
        method = RequestMethod.GET)
    default ResponseEntity<Company> companiesGet(@PathVariable("company_key") String companyKey) {
        return findOne(companyKey);
    }

    ResponseEntity<Company> findOne(String companyKey);


    /**
     * GET /companies : Search for Companies Resource route for getting a list of &#x60;Company&#x60; with filtering
     * based on provided parameters.
     *
     * @param companyKey Company key (optional, default to new ArrayList&lt;&gt;())
     * @param limit      The maximum number of &#x60;items&#x60; to return in a single request (i.e.: a single page).
     *                   (optional)
     * @param offset     The number of &#x60;items&#x60; to offset (aka skip) for pagination.  (optional, default to 0)
     * @param sortBy     Field name existing in the top level of an object in &#x60;items&#x60; by which to sort the
     *                   results. (optional)
     * @param sortOrder  Direction to sort the data. Default: &#x60;desc&#x60; if &#x60;sort_by&#x60; provided.
     *                   (optional, default to desc)
     * @return &#x60;Companies&#x60; response object (status code 200) or A &#x60;400 Bad Request&#x60; response status
     * indicates a problem with the input provided by a client request. If you are receiving this error, check your
     * request parameters are valid.  (status code 400) or A &#x60;401 Unauthorized&#x60; response status indicates that
     * the request did not include a required Authorization header, or that there was a problem authenticating the
     * client. Possible problems include an expired or invalid token, or the Authorization header is not in the expected
     * format.  (status code 401) or A &#x60;500 Internal Error&#x60; response status is returned for any application
     * and server level errors that are not already associated with another error status. A 500 is used as a generic
     * fallback error.  (status code 500)
     */
    @RequestMapping(value = "/companies",
        produces = {"application/json"},
        method = RequestMethod.GET)
    default ResponseEntity<Companies> companiesSearch(
        @Valid @RequestParam(value = "company_key", required = false) List<String> companyKey,
        @Min(0) @Max(ApplicationConstants.MAX_PAGE_SIZE) @Valid @RequestParam(value = "limit", required = false) Integer limit,
        @Min(0) @Valid @RequestParam(value = "offset", required = false, defaultValue = "0") Integer offset,
        @Valid @RequestParam(value = "sort_by", required = false) String sortBy,
        @Valid @RequestParam(value = "sort_order", required = false, defaultValue = "desc") SortOrder sortOrder) {
        return getSearchData(Params.builder()
            .companyKeys(companyKey)
            .limit(limit)
            .offset(offset)
            .sortBy(sortBy)
            .sortOrder(sortOrder)
            .build());
    }

    ResponseEntity<Companies> getSearchData(Params params);

}
