package com.banesco.module.payment_instruction_request.infrastructure.resource;

import com.banesco.common.domain.model.ApiResponse;
import com.banesco.common.domain.model.StatusResponse;
import com.banesco.module.payment_instruction_request.application.usecase.PaymentInstructionRequestUseCase;
import com.banesco.module.payment_instruction_request.domain.dto.request.PaymentInstructionRequestRequest;
import com.banesco.module.payment_instruction_request.domain.dto.response.PaymentInstructionRequestResponse;
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.Operation;
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.media.SchemaProperty;
import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;

@Slf4j
@Path("/payment-instruction-request")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PaymentInstructionRequestResource {

    private final PaymentInstructionRequestUseCase useCase;

    @Inject
    public PaymentInstructionRequestResource(
        PaymentInstructionRequestUseCase useCase
    ) {
        this.useCase = useCase;
    }

    @POST
    @Path("/initiate")
    @Operation(
        summary = "Genera informacion de la solicitud de pago multiple",
        description = "Envía la solicitud del pago multiple del cliente"
    )
    @APIResponses(value = {
        @APIResponse(
            responseCode = "200",
            description = "Operacion exitosa",
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                    implementation = ApiResponse.class,
                    properties = {
                        @SchemaProperty(
                            name = "data",
                            oneOf = {PaymentInstructionRequestResponse.class}
                        ),
                        @SchemaProperty(
                            name = "statusResponse",
                            implementation = StatusResponse.class
                        )
                    }
                ),
                examples = @ExampleObject(
                    name = "Ejemplo exitoso",
                    value = """
                    {
                      "data": {
                        "paymentInstructionTransaction": {
                            "paymentArrangement": [
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "J888888888"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04147777777"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "V333333333"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04125555555"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": "0134"
                                    },
                                    "paymentAmount": 200.0,
                                    "paymentPurpose": "Cobro a Luis",
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": "2026-12-31T16:21:06"
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "P444444444"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04163333333"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": null
                                    },
                                    "paymentAmount": null,
                                    "paymentPurpose": null,
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": null
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "V121212121"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04248888888"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": null
                                    },
                                    "paymentAmount": null,
                                    "paymentPurpose": null,
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": null
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": null
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "E888888888"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04162222222"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": null
                                    },
                                    "paymentAmount": 600.0,
                                    "paymentPurpose": "Cobro a Pedro",
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": "2026-08-11T09:09:09"
                                        }
                                    ]
                                }
                            ]
                        }
                      },
                      "statusResponse": {
                        "statusCode": "200",
                        "message": "Operacion exitosa"
                      }
                    }
                    """
                )
            )
        ),
        @APIResponse(
            responseCode = "400",
            description = "Error en formato o campo requerido",
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                    implementation = ApiResponse.class,
                    properties = {
                        @SchemaProperty(
                            name = "data",
                            oneOf = {PaymentInstructionRequestResponse.class}
                        ),
                        @SchemaProperty(
                            name = "statusResponse",
                            implementation = StatusResponse.class
                        )
                    }
                ),
                examples = {
                    @ExampleObject(
                        name = "Error VDE01 - Campo obligatorio",
                        value = """
                        {
                          "data": null,
                          "statusResponse": {
                            "statusCode": "VDE01",
                            "message": "El campo document.documentName es obligatorio"
                          }
                        }
                        """
                    ),
                    @ExampleObject(
                        name = "Error VDE02 - Valor no permitido",
                        value = """
                        {
                          "data": null,
                          "statusResponse": {
                            "statusCode": "VDE02",
                            "message": "El valor 'XYZ' no es permitido para el campo channelCode. Valores permitidos: BOLE"
                          }
                        }
                        """
                    )
                }
            )
        ),
        @APIResponse(
            responseCode = "401",
            description = "No autorizado",
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                    implementation = ApiResponse.class,
                    properties = {
                        @SchemaProperty(
                            name = "data",
                            oneOf = {PaymentInstructionRequestResponse.class}
                        ),
                        @SchemaProperty(
                            name = "statusResponse",
                            implementation = StatusResponse.class
                        )
                    }
                ),
                examples = {
                    @ExampleObject(
                        name = "Error VRN08 - Identificacion del fintechId no coincide",
                        value = """
                        {
                          "data": null,
                          "statusResponse": {
                            "statusCode": "VRN08",
                            "message": "El fintechId proporcionado no coincide con el registrado para este cliente"
                          }
                        }
                        """
                    )
                }
            )
        ),
        @APIResponse(
            responseCode = "503",
            description = "Servicio no disponible",
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                    implementation = ApiResponse.class,
                    properties = {
                        @SchemaProperty(
                            name = "data",
                            oneOf = {PaymentInstructionRequestResponse.class}
                        ),
                        @SchemaProperty(
                            name = "statusResponse",
                            implementation = StatusResponse.class
                        )
                    }
                ),
                examples = {
                    @ExampleObject(
                        name = "Error VRN04 - Fuera de horario",
                        value = """
                        {
                          "data": null,
                          "statusResponse": {
                            "statusCode": "VRN04",
                            "message": "El servicio no esta disponible fuera del horario operativo"
                          }
                        }
                        """
                    ),
                    @ExampleObject(
                        name = "Error VDR13 - OSB no disponible",
                        value = """
                        {
                          "data": null,
                          "statusResponse": {
                            "statusCode": "VDR13",
                            "message": "El servicio OSB no esta disponible en este momento"
                          }
                        }
                        """
                    )
                }
            )
        )
    })
    public Response initiate(
        @RequestBody(
            description = "Request de la solicitud del pago del cliente",
            content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(implementation = PaymentInstructionRequestRequest.class),
                examples = @ExampleObject(
                    name = "Ejemplo de request",
                    value = """
                    {
                        "customerReferenceFintechId": "provider-test",
                        "appId": "DANIAPP",
                        "paymentInstructionTransaction": {
                            "paymentInstruction": {
                                "paymentArrangement": {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04140000000"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "J999999999"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": "0134"
                                    },
                                    "paymentAmount": 500.00,
                                    "paymentPurpose": "Pagos de seguro",
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": "2026-03-03T12:07:57"
                                        }
                                    ]
                                }
                            },
                            "paymentArrangement": [
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGEE_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04147777777"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "J888888888"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                },
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04125555555"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "V333333333"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "bankingProduct": {
                                        "productName": "0134"
                                    },
                                    "paymentAmount": 200.00,
                                    "paymentPurpose": "Cobro a Luis",
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": "2026-12-31T16:21:06"
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04163333333"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "P444444444"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04248888888"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "V121212121"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ]
                                },
                                {
                                    "arrangement": [
                                        {
                                            "arrangementInvolvement": [
                                                {
                                                    "arrangementInvolvementType": "PARTY_IS_OBLIGOR_IN_ARRANGEMENT",
                                                    "partyReference": {
                                                        "partyIdentification": [
                                                            {
                                                                "partyIdentificationType": "TELEPHONE_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "04162222222"
                                                                }
                                                            },
                                                            {
                                                                "partyIdentificationType": "IDENTITY_CARD_NUMBER",
                                                                "partyIdentification": {
                                                                    "identifierValue": "E888888888"
                                                                }
                                                            }
                                                        ]
                                                    }
                                                }
                                            ]
                                        }
                                    ],
                                    "paymentAmount": 600.00,
                                    "paymentPurpose": "Cobro a Pedro",
                                    "paymentDate": [
                                        {
                                            "dateType": "EFFECTIVITY_DATE",
                                            "date": "2026-08-11T09:09:09"
                                        }
                                    ]
                                }
                            ]
                        },
                        "procedureRequest": {
                            "instructionPurposeType": "BOLE"
                        },
                        "device": {
                            "deviceType": "Mobile",
                            "deviceDescription": "Xiaomi Note 11 PRO",
                            "deviceIp": "127.0.0.1",
                            "deviceSessionReference": "12345678901304"
                        }
                    }
                    """
                )
            )
        )
        PaymentInstructionRequestRequest request
    ) {
        log.info("Iniciando consulta para instruccion masiva del cliente: {}", request.getRecipientId());

        return useCase.execute(request);
    }
}