package de.avatic.lcc.controller.configuration;

import de.avatic.lcc.dto.configuration.countries.view.CountryDetailDTO;
import de.avatic.lcc.dto.generic.CountryDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.access.CountryService;
import de.avatic.lcc.util.exception.badrequest.NotFoundException;
import jakarta.validation.constraints.Min;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

/**
 * REST controller for managing country-related data.
 * Provides endpoints to retrieve country details and lists.
 */
@RestController
@RequestMapping("/api/countries")
@Validated
public class CountryController {

    private final CountryService countryService;

    /**
     * Constructs a new instance of {@link CountryController} with the given {@link CountryService}.
     *
     * @param countryService the service responsible for interacting with country data
     */
    public CountryController(CountryService countryService) {
        this.countryService = countryService;
    }

    /**
     * Retrieves a paginated list of countries based on the provided filters.
     *
     * @param limit  the maximum number of countries to return per page (default is 20)
     * @param page   the page number to return (default is 0)
     * @param filter the filter query to apply on the country list (default is an empty string for no filtering)
     * @return a {@link ResponseEntity} containing a list of {@link CountryDTO} objects
     * and additional pagination headers
     */
    @GetMapping({"/", ""})
    @PreAuthorize("hasRole('SUPER')")
    public ResponseEntity<List<CountryDTO>> listCountries(@RequestParam(defaultValue = "20") @Min(1) int limit,
                                                          @RequestParam(defaultValue = "1") @Min(1) int page,
                                                          @RequestParam(required = false) Optional<String> filter) {

        var auth = SecurityContextHolder.getContext().getAuthentication();

        SearchQueryResult<CountryDTO> countries = countryService.listCountries(filter, page, limit);

        return ResponseEntity.ok()
                .header("X-Total-Count", String.valueOf(countries.getTotalElements()))
                .header("X-Page-Count", String.valueOf(countries.getTotalPages()))
                .header("X-Current-Page", String.valueOf(countries.getPage()))
                .body(countries.toList());

    }

    /**
     * Retrieves a complete list of countries with optional filtering.
     *
     * @param filter the filter query to apply on the country list (default is an empty string for no filtering)
     * @return a {@link ResponseEntity} containing a list of all {@link CountryDTO} objects
     * and additional headers with metadata
     */
    @GetMapping({"/all", "/all/"})
    @PreAuthorize("hasRole('SUPER')")
    public ResponseEntity<List<CountryDTO>> allCountries(@RequestParam(required = false) Optional<String> filter) {

        SearchQueryResult<CountryDTO> countries = countryService.listCountries(filter);

        return ResponseEntity.ok()
                .header("X-Total-Count", String.valueOf(countries.getTotalElements()))
                .header("X-Page-Count", String.valueOf(countries.getTotalPages()))
                .header("X-Current-Page", String.valueOf(countries.getPage()))
                .body(countries.toList());

    }

    /**
     * Retrieves detailed information about a specific country based on its ID.
     *
     * @param id            the identifier of the country to retrieve
     * @param propertySetId an optional query parameter indicating the property set to use for retrieving country properties;
     *                      defaults to 0, which retrieves properties from the current set
     * @return a {@link ResponseEntity} containing a {@link CountryDetailDTO} with the country's details
     */
    @GetMapping({"/{id}", "/{id}/"})
    @PreAuthorize("hasRole('SUPER')")
    public ResponseEntity<CountryDetailDTO> getCountryDetails(@PathVariable String id, @RequestParam(name = "property_set", defaultValue = "0", required = false) @Min(0) Integer propertySetId) {
        return ResponseEntity.ok(countryService.getCountry(id, propertySetId).orElseThrow(() -> new NotFoundException(NotFoundException.NotFoundType.COUNTRY, id)));
    }
}
