package jumapacelaya.gob.mx.predios.controlador;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import jumapacelaya.gob.mx.predios.servicio.PredioServicio;
import jumapacelaya.gob.mx.predios.dto.PredioDTO;

@Controller("/predios")
public class PredioControlador {

    private final PredioServicio predioServicio;

    public PredioControlador(PredioServicio predioServicio) {
        this.predioServicio = predioServicio;
    }

    @Get("/{id}")
    public PredioDTO obtenerPredio(Long id) {
        return predioServicio.obtenerPredio(id);
    }

    @Get("/var/{id}")
    public HttpResponse<?> obtenerPredioVar(@PathVariable Long id) {
        Optional<PredioDTO> predio = predioServicio.obtenerPredioVar(id);
        if (predio.isPresent()) {
            return HttpResponse.ok(predio.get());
        } else {
            return HttpResponse.notFound(Collections.singletonMap("message", "Predio no encontrado"));
        }
    }

    @Get("/atm/{referencia}")
    public HttpResponse<?> obtenerPredioATM(@PathVariable String referencia) {
        return predioServicio.obtenerPredioATM(referencia)
            .<HttpResponse<?>>map(HttpResponse::ok)
            .orElse(HttpResponse.notFound(
                Map.of("message", "Predio no encontrado para referencia: " + referencia)
            )
        );
    }

    @Get("/apc/{valor}")
    public HttpResponse<?> obtenerPredioAPC(String valor) {
        Optional<PredioDTO> resultado = predioServicio.obtenerPredioAPC(valor);
        return resultado
            .<HttpResponse<?>>map(HttpResponse::ok)
            .orElse(HttpResponse.notFound(Map.of("message", "Predio no encontrado")
        ));
    }

    @Get("/appots/{id}")
    public HttpResponse<?> obtenerPredioAppOTs(Long id) {
        return predioServicio.obtenerPredioAppOTs(id)
            .<HttpResponse<?>>map(HttpResponse::ok)
            .orElseGet(() -> {
                Map<String, String> error = new HashMap<>();
                error.put("message", "Predio AppOTs no encontrado");
                return HttpResponse.status(HttpStatus.NOT_FOUND).body(error);
                
            }
        );
    }

    @Get("/direccion/{predioId}")
    public HttpResponse<?> obtenerDireccionPredio(@PathVariable Long predioId) {
        return predioServicio.obtenerDireccionPredio(predioId)
            .<HttpResponse<?>>map(HttpResponse::ok)
            .orElse(HttpResponse.notFound(
                Map.of("message", "Predio no encontrado")
            )
        );
    }

    @Get("/direccion-cooper/{predioId}")
    public HttpResponse<Map<String, String>> obtenerDireccionCooper(@PathVariable Long predioId) {
        String mensaje = predioServicio.obtenerDireccionCooper(predioId);
        return HttpResponse.ok(Map.of("message", mensaje));
    }

    @Get("/direccion-coopers/{predioId}")
    public MutableHttpResponse<Map<String, Optional<String>>> obtenerDireccionCoopers(@PathVariable Long predioId) {
        Optional<String> mensaje = predioServicio.obtenerDireccionCoopers(predioId);
        return HttpResponse.ok(Map.of("message", mensaje));
    }

    @Get("/coordx/{predioId}")
    public HttpResponse<Double> obtenerCoordX(@PathVariable Long predioId) {
        return predioServicio.obtenerCoordX(predioId)
        .map(HttpResponse::ok)
        .orElse(HttpResponse.notFound());
    }

    @Get("/coordy/{predioId}")
    public HttpResponse<Double> obtenerCoordY(@PathVariable Long predioId) {
        return predioServicio.obtenerCoordY(predioId)
        .map(HttpResponse::ok)
        .orElse(HttpResponse.notFound());
    }

    @Get("/cliente/{predioId}")
    public HttpResponse<Long> obtenerClienteId(@PathVariable Long predioId) {
        return predioServicio.obtenerClienteId(predioId)
            .map(HttpResponse::ok)
            .orElse(HttpResponse.notFound());
    }

    @Get("/ot/{predioId}/{motivoId}")
    public HttpResponse<Long> obtenerOT(@PathVariable Long predioId,
        @PathVariable String motivoId) {
            return predioServicio.obtenerOT(predioId, motivoId)
                .map(HttpResponse::ok)
                .orElse(HttpResponse.notFound()
        );
    }

    @Get("/situacion-corte/{predioId}/{tipo}")
    public HttpResponse<String> obtenerSituacionCorte(@PathVariable Long predioId,
        @PathVariable String tipo) {
            return predioServicio.obtenerSituacionCorte(predioId, tipo)
                .map(HttpResponse::ok)
                .orElse(HttpResponse.noContent()
        );
    }

}
