package com.banesco.application.rest.controllers;

import com.banesco.application.helper.UpdateCardStatusRequestValidator;
import com.banesco.common.application.exception.BanBackendException;
import com.banesco.common.application.exception.BanRuntimeException;
import com.banesco.common.domain.dto.bian.device.JsonHelper;
import com.banesco.common.domain.dto.bian.device.LoggerHelper;
import com.banesco.common.domain.model.BackResponse;
import com.banesco.commons.config.AppConf;
import com.banesco.domain.bian.request.RecUpdateCardStatusRequest;
import com.banesco.domain.bian.response.RecUpdateCardStatusResponse;
import com.banesco.domain.models.CurrentState;
import com.banesco.domain.ports.inbound.RegisterSecurityUseCase;
import com.banesco.domain.ports.inbound.UpdateCardStatusUseCase;
import com.banesco.infrastructure.dtos.RegisterSecurityRq;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.info.Info;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.ExampleObject;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;

@OpenAPIDefinition(info = @Info(
        title = "rec-update-card-status",
        version = "1.0",
        description = "API Recepcion - Cancelación de TDD")
)
@Path("/card/status/update")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
public class UpdateCardStatusController {


    private final UpdateCardStatusRequestValidator updateCardStatusRequestValidator;
    private final UpdateCardStatusUseCase updateCardStatusUseCase;
    private final RegisterSecurityUseCase registerSecurityUseCase;

    @Inject
    AppConf appConf;

    @Inject
    public UpdateCardStatusController(
            UpdateCardStatusRequestValidator updateCardStatusRequestValidator,
            UpdateCardStatusUseCase updateCardStatusUseCase,
            RegisterSecurityUseCase registerSecurityUseCase

    ) {

        this.updateCardStatusRequestValidator = updateCardStatusRequestValidator;
        this.updateCardStatusUseCase = updateCardStatusUseCase;
        this.registerSecurityUseCase = registerSecurityUseCase;
    }

    @PUT
    @Operation(
            summary = "updateCardStatus",
            description = "Permite cambiar el estatus de las tarjetas de los clientes."
    )
    @Parameter(
            name = "customerReferenceFintechId",
            description = "ID de la fintech",
            example = "pranical-test"
    )
    @Parameter(
            name = "appId",
            description = "ID de la aplicación",
            example = "DANIAPP"
    )
    @RequestBody(
            description = "Datos de la solicitud para actualizar el estatus de la tarjeta",
            required = true,
            content = @Content(
                    mediaType = MediaType.APPLICATION_JSON,
                    schema = @Schema(implementation = RecUpdateCardStatusRequest.class),
                    examples = {
                            @ExampleObject(
                                    name = "Ejemplo exitoso",
                                    summary = "Petición con datos válidos",
                                    value = "{\n" +
                                            "  \"customerReference\": {\n" +
                                            "    \"customerIdType\": \"J\",\n" +
                                            "    \"customerId\": \"500634269\"\n" +
                                            "  },\n" +
                                            "  \"device\": {\n" +
                                            "    \"deviceType\": \"Mobile\",\n" +
                                            "    \"deviceDescription\": \"Xiaomi Note 11 PRO\",\n" +
                                            "    \"deviceIp\": \"127.0.0.1\",\n" +
                                            "    \"deviceSessionReference\": \"12345678901304\"\n" +
                                            "  },\n" +
                                            "  \"cardReference\": {\n" +
                                            "    \"cardType\": \"DebitCard\",\n" +
                                            "    \"cardNumber\": \"6012-8862-0791-7605\",\n" +
                                            "    \"cardStatusCode\": \"52\",\n" +
                                            "    \"cardStatusAction\": \"CV\",\n" +
                                            "    \"cardStatusReason\": \"Bloqueo Temporal\"\n" +
                                            "  }\n" +
                                            "}"
                            ),
                            @ExampleObject(
                                    name = "Ejemplo Error de validación",
                                    summary = "Petición con formato inválido",
                                    value = "{\n" +
                                            "  \"customerReference\": {\n" +
                                            "    \"customerIdType\": \"V\",\n" +
                                            "    \"customerId\": \"500634269\"\n" +
                                            "  },\n" +
                                            "  \"device\": {\n" +
                                            "    \"deviceType\": \"Mobile\",\n" +
                                            "    \"deviceDescription\": \"Xiaomi Note 11 PRO\",\n" +
                                            "    \"deviceIp\": \"127.0.0.1\",\n" +
                                            "    \"deviceSessionReference\": \"12345678901304\"\n" +
                                            "  },\n" +
                                            "  \"cardReference\": {\n" +
                                            "    \"cardType\": \"DebitCard\",\n" +
                                            "    \"cardNumber\": \"6012886207917605\",\n" +
                                            "    \"cardStatusCode\": \"52\",\n" +
                                            "    \"cardStatusAction\": \"CV\",\n" +
                                            "    \"cardStatusReason\": \"Bloqueo Temporal\"\n" +
                                            "  }\n" +
                                            "}"
                            )
                    }
            )
    )
    @APIResponses(value = {
            @APIResponse(
                    responseCode = "200",
                    description = "Operación exitosa",

                    content = @Content(
                            mediaType = MediaType.APPLICATION_JSON,
                            schema = @Schema(implementation = RecUpdateCardStatusResponse.class),
                            examples = @ExampleObject(
                                    name = "Ejemplo exitoso",
                                    value = "{\"statusResponse\":{\"status\":\"ok\",\"statusCode\":\"200\",\"message\":\"Operacion exitosa\",\"requestId\":\"UCSS123456789\"}}"
                            )
                    )
            ),
            @APIResponse(
                    responseCode = "400",
                    description = "Error en formato o campo requerido",
                    content = @Content(
                            mediaType = MediaType.APPLICATION_JSON,
                            schema = @Schema(implementation = RecUpdateCardStatusResponse.class),
                            examples = @ExampleObject(
                                    name = "Ejemplo Error de validación",
                                    value = "{\"statusResponse\":{\"status\":\"error\",\"statusCode\":\"VDE02\",\"message\":\"VDE02 - Error en formato del campo: cardReference.cardNumber\",\"requestId\":\"UCSS123456789\"}}"
                            )
                    )
            )
    })
    public Response updateCardStatus(
            @HeaderParam("customerReferenceFintechId") String customerReferenceFintechId,
            @HeaderParam("appId") String appId,
            RecUpdateCardStatusRequest request) {

        long startExecution = System.currentTimeMillis();
        CurrentState currentState = appConf.getCurrentState(appId, customerReferenceFintechId);
        RecUpdateCardStatusResponse dataResponse = null;
        log.info("INICIO =>");
        log.info("[HEADERS {}: \ncustomerReferenceFintechId: {}\nappId: {}]",
                currentState.requestId(), customerReferenceFintechId, appId);

        log.info(LoggerHelper.buildInfoRequest(currentState.requestId(), JsonHelper.getJsonFromObject(request)));
        boolean mustWriteTrace = false;
        String backendCode = "500";
        String target = null;

        try {
            // Validate Request
            updateCardStatusRequestValidator.validatedRequest(
                    customerReferenceFintechId,
                    appId,
                    request
            );


            mustWriteTrace = true;

            updateCardStatusUseCase.execute(
                    currentState,
                    request
            );

            backendCode = "200";
        } catch (BanRuntimeException e) {
            backendCode = e.getStatusCode().getStatusCode();
            log.error(LoggerHelper.buildError(currentState.requestId(), backendCode + " - " + e.getMessage()));
            if (e.getTarget() != null) {
                target = e.getTarget();
            }

        } catch (BanBackendException e) {
            backendCode = e.getBackendCode();
            log.error(LoggerHelper.buildError(currentState.requestId(), backendCode + " - " + e.getMessage()));
            if (e.getTarget() != null) {
                target = e.getTarget();
            }

        } catch (Exception e) {
            log.error(LoggerHelper.buildError(currentState.requestId(), backendCode + " - " + e.getMessage()));
        }

        BackResponse backResponse = appConf.responsesMap.get(backendCode);

        if (backResponse == null) {
            backResponse = appConf.messageService.geStatusResponse(
                    appConf.getRecUpdateCardMessageKey(),
                    backendCode);
            appConf.responsesMap.put(backendCode, backResponse);
        }

        RecUpdateCardStatusResponse response = new RecUpdateCardStatusResponse();
        response.setStatusResponse(appConf.messageService.backToStatusResponse(currentState.requestId(), backResponse, target));

        String outputJson = response.toString();

        log.info(LoggerHelper.buildInfoResponse(currentState.requestId(), outputJson));

        if (mustWriteTrace) { // writeTrace

            /*
            registerSecurityUseCase.writeTrace(currentState.requestId(),
                    getRegisterSecurityRq(
                            currentState.fintechId(),
                            request,
                            response,
                            outputJson,
                            System.currentTimeMillis() - startExecution,
                            backResponse.getHttpCode()
                    ));*/
        }

        return Response.status(backResponse.getHttpCode())
                .entity(outputJson)
                .build();
    }


    private RegisterSecurityRq getRegisterSecurityRq(
            String fintechId,
            RecUpdateCardStatusRequest request,
            RecUpdateCardStatusResponse response,
            String outputJson,
            long timeExecution,
            int httpCode
    ) {
        // Building Trace Data
        RegisterSecurityRq registerSecurityRequest = new RegisterSecurityRq();


        return registerSecurityRequest;

    }
}
