package com.banesco.domain.services;

import com.banesco.common.application.exception.BanBackendException;
import com.banesco.common.application.exception.BanRuntimeException;
import com.banesco.common.domain.dto.bian.customer.CustomerReference;
import com.banesco.common.domain.dto.bian.device.JsonHelper;
import com.banesco.common.domain.dto.bian.device.StringHelper;
import com.banesco.common.domain.dto.bian.response.StatusResponse;
import com.banesco.common.domain.model.RedisParam;
import com.banesco.commons.config.AppConf;
import com.banesco.commons.config.StatusCodes;
import com.banesco.domain.bian.request.BusUpdateCardStatusRequest;
import com.banesco.domain.ports.inbound.UpdateCardStatusUseCase;
import com.banesco.domain.ports.outbound.PaymentCardPort;
import com.banesco.domain.ports.outbound.RedisPort;
import com.banesco.infrastructure.dtos.CustomerProduct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import java.util.List;

@ApplicationScoped
public class UpdateCardStatusService implements UpdateCardStatusUseCase {


    private final PaymentCardPort paymentCardPort;
    private final String RESULT_OK = StatusCodes.SUCCESS_OPERATION.getStatusCode();

    private final RedisParam redisParam;

    private final RedisPort redisPort;

    @Inject
    public UpdateCardStatusService(AppConf appConf, PaymentCardPort paymentCardPort, RedisPort redisPort) {
        this.paymentCardPort = paymentCardPort;
        this.redisPort = redisPort;
        redisParam = JsonHelper.getObjectFromJson(appConf.getConfigEnv().getValue("api.redis.get-evaluate-customer-product", String.class), RedisParam.class);

    }


    @Override
    public void execute(BusUpdateCardStatusRequest request) {


        CustomerProduct customerProduct = getCustomerProductByCardNumber(request.getCustomerReference(),
                request.getDevice().getDeviceSessionReference(),
                request.getCardReference().getCardNumber());


        StatusResponse statusResponse = paymentCardPort.updateCardStatus(customerProduct.getClearAccount(), request);

        if (!statusResponse.statusCode().equals(RESULT_OK)) {
            throw new BanBackendException(statusResponse.statusCode(), statusResponse.message());
        }

    }

    private CustomerProduct getCustomerProductByCardNumber(CustomerReference customerReference, String deviceSessionReference, String cardNumber) {
        String redisKey = redisParam.getPrefix().formatted(customerReference.getCustomerIdType(),
                customerReference.getCustomerId(),
                deviceSessionReference);

        String products = redisPort.findValue(redisKey);

        if (products == null) {
            throw new BanRuntimeException(StatusCodes.REDIS_DATA_NOT_FOUND);
        }
        CustomerProduct customerProduct = null;
        try {
            List<CustomerProduct> productList = JsonHelper.getListFromJson(products, CustomerProduct.class);
            if (productList != null) {
                customerProduct = productList.stream().filter(account -> account.getMaskedAccount().equals(cardNumber))
                        .findFirst()
                        .orElse(null);
            }
        } catch (Exception e) {
            throw new BanRuntimeException(StatusCodes.INTERNAL_ERROR, "Error parsing customer products from Redis");
        }

        if (customerProduct == null || StringHelper.isEmpty(customerProduct.getClearAccount())) {
            throw new BanRuntimeException(StatusCodes.REDIS_DATA_NOT_FOUND);
        }

        return customerProduct;

    }


}
