package org.jpos.tcpay.service;

import org.jpos.iso.ISOMsg;
import org.jpos.tcpay.db.entity.AcquirerTerminal;
import org.jpos.tcpay.db.entity.AcquirerTerminalBatch;
import org.jpos.tcpay.db.entity.AcquirerTerminalStan;
import org.jpos.tcpay.db.repository.AcquirerTerminalStanRepository;
import org.jpos.tcpay.db.repository.AcquirerTerminalBatchRepository;
import org.jpos.util.AppLogger;

import java.time.LocalDate;

/**
 * Service for managing Stan (DE11) and Batch (DE62) numbers for acquirer terminal transactions.
 * Handles increment/reset logic and excludes Reversal and Void transactions.
 */
public class StanBatchNumberService {
    
    private final AcquirerTerminalStanRepository stanRepository;
    private final AcquirerTerminalBatchRepository batchRepository;
    private final AppLogger logger = new AppLogger();

    public StanBatchNumberService(AcquirerTerminalStanRepository stanRepository,
                                  AcquirerTerminalBatchRepository batchRepository) {
        this.stanRepository = stanRepository;
        this.batchRepository = batchRepository;
    }
    
    /**
     * Get next Stan number for the acquirer terminal if transaction type allows it
     */
    public Integer getNextStanNumber(final AcquirerTerminal acquirerTerminalId, ISOMsg isoMsg) {
        try {
            LocalDate today = LocalDate.now();
            
            // Reset Stan if needed (daily reset)
            boolean isRest = stanRepository.resetStanIfNeeded(acquirerTerminalId, today);
            Integer nextStan = 1;
            if (isRest) {
                nextStan = stanRepository.find(acquirerTerminalId)
                        .map(AcquirerTerminalStan::getCurrentStan)
                        .orElse(1);
            } else {
                nextStan = stanRepository.getAndIncrementStan(acquirerTerminalId);
            }
            
            logger.log("Generated Stan number: " + nextStan + " for acquirer terminal: " + acquirerTerminalId.getTerminalId());
            return nextStan;
        } catch (Exception e) {
            logger.exceptionLog(e);
            return null; // Fallback to existing logic
        }
    }
    
    /**
     * Get next Batch number for the acquirer terminal if transaction type allows it
     */
    public Integer getBatchNumber(AcquirerTerminal acquirerTerminalId, ISOMsg isoMsg) {

        try {
            // Get and increment Batch number atomically
            AcquirerTerminalBatch acquirerTerminalBatch = batchRepository.findOrCreate(acquirerTerminalId);
            
            logger.log("Getting Batch number: " + acquirerTerminalBatch.getCurrentBatch() + " for acquirer terminal: " + acquirerTerminalId.getTerminalId());
            return acquirerTerminalBatch.getCurrentBatch();
        } catch (Exception e) {
            logger.exceptionLog(e);
            return null; // Fallback to existing logic
        }
    }

}