package vn.azteam.tpf.web.rest;

import com.codahale.metrics.annotation.Timed;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import vn.azteam.tpf.service.TBCustomerQueryService;
import vn.azteam.tpf.service.TBCustomerService;
import vn.azteam.tpf.service.TBLocationOfCustomerService;
import vn.azteam.tpf.service.dto.TBCustomerCriteria;
import vn.azteam.tpf.service.dto.TBCustomerDTO;
import vn.azteam.tpf.web.rest.errors.BadRequestAlertException;
import vn.azteam.tpf.web.rest.util.HeaderUtil;
import vn.azteam.tpf.web.rest.util.PaginationUtil;
import vn.azteam.tpf.service.dto.TBLocationOfCustomerDTO;
import vn.azteam.tpf.service.dto.TBLocationOfCustomerCriteria;
import vn.azteam.tpf.service.TBLocationOfCustomerQueryService;
import io.github.jhipster.web.util.ResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.net.URISyntaxException;

import java.util.List;
import java.util.Optional;

/**
 * REST controller for managing TBLocationOfCustomer.
 */
@RestController
@RequestMapping("/api")
public class TBLocationOfCustomerResource {

    private final Logger log = LoggerFactory.getLogger(TBLocationOfCustomerResource.class);

    private static final String ENTITY_NAME = "tBLocationOfCustomer";

    private final TBLocationOfCustomerService tBLocationOfCustomerService;

    private final TBLocationOfCustomerQueryService tBLocationOfCustomerQueryService;

    private final TBCustomerService tbCustomerService;

    private final TBCustomerQueryService tbCustomerQueryService;

    public TBLocationOfCustomerResource(TBLocationOfCustomerService tBLocationOfCustomerService,
                                        TBLocationOfCustomerQueryService tBLocationOfCustomerQueryService,
                                        TBCustomerService tbCustomerService,
                                        TBCustomerQueryService tbCustomerQueryService) {
        this.tBLocationOfCustomerService = tBLocationOfCustomerService;
        this.tBLocationOfCustomerQueryService = tBLocationOfCustomerQueryService;
        this.tbCustomerService = tbCustomerService;
        this.tbCustomerQueryService = tbCustomerQueryService;
    }

    /**
     * POST  /tb-location-of-customers : Create a new tBLocationOfCustomer.
     *
     * @param tBLocationOfCustomerDTO the tBLocationOfCustomerDTO to create
     * @return the ResponseEntity with status 201 (Created) and with body the new tBLocationOfCustomerDTO, or with status 400 (Bad Request) if the tBLocationOfCustomer has already an ID
     * @throws URISyntaxException if the Location URI syntax is incorrect
     */
    @PostMapping("/tb-location-of-customers")
    @Timed
    public ResponseEntity<TBLocationOfCustomerDTO> createTBLocationOfCustomer(@RequestBody TBLocationOfCustomerDTO tBLocationOfCustomerDTO) throws URISyntaxException {
        log.debug("REST request to save TBLocationOfCustomer : {}", tBLocationOfCustomerDTO);
        if (tBLocationOfCustomerDTO.getId() != null) {
            throw new BadRequestAlertException("A new tBLocationOfCustomer cannot already have an ID", ENTITY_NAME, "idexists");
        }
        TBLocationOfCustomerDTO result = tBLocationOfCustomerService.save(tBLocationOfCustomerDTO);
        return ResponseEntity.created(new URI("/api/tb-location-of-customers/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

    /**
     * PUT  /tb-location-of-customers : Updates an existing tBLocationOfCustomer.
     *
     * @param tBLocationOfCustomerDTO the tBLocationOfCustomerDTO to update
     * @return the ResponseEntity with status 200 (OK) and with body the updated tBLocationOfCustomerDTO,
     * or with status 400 (Bad Request) if the tBLocationOfCustomerDTO is not valid,
     * or with status 500 (Internal Server Error) if the tBLocationOfCustomerDTO couldn't be updated
     * @throws URISyntaxException if the Location URI syntax is incorrect
     */
    @PutMapping("/tb-location-of-customers")
    @Timed
    public ResponseEntity<TBLocationOfCustomerDTO> updateTBLocationOfCustomer(@RequestBody TBLocationOfCustomerDTO tBLocationOfCustomerDTO) throws URISyntaxException {
        log.debug("REST request to update TBLocationOfCustomer : {}", tBLocationOfCustomerDTO);
        if (tBLocationOfCustomerDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        TBLocationOfCustomerDTO result = tBLocationOfCustomerService.save(tBLocationOfCustomerDTO);
        return ResponseEntity.ok()
            .headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, tBLocationOfCustomerDTO.getId().toString()))
            .body(result);
    }

    /**
     * GET  /tb-location-of-customers : get all the tBLocationOfCustomers.
     *
     * @param pageable the pagination information
     * @param criteria the criterias which the requested entities should match
     * @return the ResponseEntity with status 200 (OK) and the list of tBLocationOfCustomers in body
     */
    @GetMapping("/tb-location-of-customers")
    @Timed
    public ResponseEntity<List<TBLocationOfCustomerDTO>> getAllTBLocationOfCustomers(TBLocationOfCustomerCriteria criteria, Pageable pageable) {
        log.debug("REST request to get TBLocationOfCustomers by criteria: {}", criteria);
        Page<TBLocationOfCustomerDTO> page = tBLocationOfCustomerQueryService.findByCriteria(criteria, pageable);
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/tb-location-of-customers");
        return ResponseEntity.ok().headers(headers).body(page.getContent());
    }

    /**
    * GET  /tb-location-of-customers/count : count all the tBLocationOfCustomers.
    *
    * @param criteria the criterias which the requested entities should match
    * @return the ResponseEntity with status 200 (OK) and the count in body
    */
    @GetMapping("/tb-location-of-customers/count")
    @Timed
    public ResponseEntity<Long> countTBLocationOfCustomers(TBLocationOfCustomerCriteria criteria) {
        log.debug("REST request to count TBLocationOfCustomers by criteria: {}", criteria);
        return ResponseEntity.ok().body(tBLocationOfCustomerQueryService.countByCriteria(criteria));
    }

    /**
     * GET  /tb-location-of-customers/:id : get the "id" tBLocationOfCustomer.
     *
     * @param id the id of the tBLocationOfCustomerDTO to retrieve
     * @return the ResponseEntity with status 200 (OK) and with body the tBLocationOfCustomerDTO, or with status 404 (Not Found)
     */
    @GetMapping("/tb-location-of-customers/{id}")
    @Timed
    public ResponseEntity<TBLocationOfCustomerDTO> getTBLocationOfCustomer(@PathVariable Long id) {
        log.debug("REST request to get TBLocationOfCustomer : {}", id);
        Optional<TBLocationOfCustomerDTO> tBLocationOfCustomerDTO = tBLocationOfCustomerService.findOne(id);
        return ResponseUtil.wrapOrNotFound(tBLocationOfCustomerDTO);
    }

    /**
     * DELETE  /tb-location-of-customers/:id : delete the "id" tBLocationOfCustomer.
     *
     * @param id the id of the tBLocationOfCustomerDTO to delete
     * @return the ResponseEntity with status 200 (OK)
     */
    @DeleteMapping("/tb-location-of-customers/{id}")
    @Timed
    public ResponseEntity<Void> deleteTBLocationOfCustomer(@PathVariable Long id) {
        log.debug("REST request to delete TBLocationOfCustomer : {}", id);
        tBLocationOfCustomerService.delete(id);
        return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
    }

    /**
     * SEARCH  /_search/tb-location-of-customers?query=:query : search for the tBLocationOfCustomer corresponding
     * to the query.
     *
     * @param query the query of the tBLocationOfCustomer search
     * @param pageable the pagination information
     * @return the result of the search
     */
    @GetMapping("/_search/tb-location-of-customers")
    @Timed
    public ResponseEntity<List<TBLocationOfCustomerDTO>> searchTBLocationOfCustomers(@RequestParam String query, Pageable pageable) {
        log.debug("REST request to search for a page of TBLocationOfCustomers for query {}", query);
        Page<TBLocationOfCustomerDTO> page = tBLocationOfCustomerService.search(query, pageable);
        HttpHeaders headers = PaginationUtil.generateSearchPaginationHttpHeaders(query, page, "/api/_search/tb-location-of-customers");
        return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
    }

    /**
     * GET  /tb-location-of-customers : get the tBLocationOfCustomers by slug name of customer.
     *
     * @param pageable the pagination information
     * @return the ResponseEntity with status 200 (OK) and the list of tBLocationOfCustomers in body
     */
    @GetMapping("/tb-location-of-customers-by-slug-name/{slugName}")
    @Timed
    public ResponseEntity<List<TBLocationOfCustomerDTO>> getAllTBLocationOfCustomers(@PathVariable String slugName, Pageable pageable) {
        TBCustomerCriteria tbCustomerCriteria = new TBCustomerCriteria();
        StringFilter slugNameFilter = new StringFilter();
        slugNameFilter.equals(slugName);
        tbCustomerCriteria.setSlugName(slugNameFilter);
        List<TBCustomerDTO> tbCustomerDTOs = tbCustomerQueryService.findByCriteria(tbCustomerCriteria);
        if(tbCustomerDTOs != null && tbCustomerDTOs.size() > 0) {
            TBLocationOfCustomerCriteria tbLocationOfCustomerCriteria = new TBLocationOfCustomerCriteria();
            LongFilter tbCustomerIdFilter = new LongFilter();
            tbCustomerIdFilter.equals(tbCustomerDTOs.get(0).getId());
            tbLocationOfCustomerCriteria.setTbCustomerId(tbCustomerIdFilter);
            List<TBLocationOfCustomerDTO> tbLocationOfCustomerDTOs = tBLocationOfCustomerQueryService.findByCriteria(tbLocationOfCustomerCriteria);
            return ResponseEntity.ok().headers(null).body(tbLocationOfCustomerDTOs);
        }
        return null;
    }
}
