Subversion Repositories SmartDukaan

Rev

Rev 35868 | Rev 36000 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.service;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class AgentLiveStatusService {

    // In-memory map to store agent status by authId
    private final Map<Integer, AgentStatus> agentStatusMap = new ConcurrentHashMap<>();
    // Caller ID (Knowlarity SR Number) to Auth ID mapping (loaded from sip_master)
    private final Map<String, Integer> callerIdToAuthIdMap = new ConcurrentHashMap<>();
    // SR Number to Auth ID mapping (loaded from sip_master)
    private final Map<String, Integer> srNumberToAuthIdMap = new ConcurrentHashMap<>();
    // Agent name to Auth ID mapping (fallback)
    private final Map<String, Integer> agentNameToAuthIdMap = new ConcurrentHashMap<>();
    @Autowired
    private SessionFactory sessionFactory;
    private String lastError = null;
    private int lastQueryCount = 0;

    /**
     * Load mapping from sip_master table on startup
     * caller_id in sip_master = SR Number on Knowlarity dashboard
     * sip_master has auth_id directly
     */
    @PostConstruct
    public void loadMappingFromDatabase() {
        try {
            Session session = sessionFactory.openSession();

            // Query to get caller_id, auth_user.id, first_name from sip_master
            // Join with auth_user to get correct auth_id used by rbm_call_target page
            String sql = "SELECT sm.caller_id, au.id, sm.first_name " +
                    "FROM auth.sip_master sm " +
                    "JOIN auth.auth_user au ON sm.email_id = au.email_id " +
                    "WHERE au.id IS NOT NULL";

            List<Object[]> results = session.createNativeQuery(sql).getResultList();
            lastQueryCount = results.size();

            for (Object[] row : results) {
                String callerId = row[0] != null ? row[0].toString().trim() : "";
                int authId = row[1] != null ? ((Number) row[1]).intValue() : 0;
                String firstName = row[2] != null ? row[2].toString().trim() : "";

                if (authId > 0) {
                    // Map by caller_id if available
                    if (!callerId.isEmpty()) {
                        callerIdToAuthIdMap.put(callerId, authId);
                    }
                    // Map by first_name for name-based matching
                    if (!firstName.isEmpty()) {
                        agentNameToAuthIdMap.put(firstName.toLowerCase(), authId);
                        System.out.println("Mapping: '" + firstName + "' -> authId=" + authId + " (caller_id=" + callerId + ")");
                    }
                }
            }

            session.close();
            System.out.println("Loaded " + callerIdToAuthIdMap.size() + " caller_id -> auth_id mappings from sip_master");
            System.out.println("Loaded " + agentNameToAuthIdMap.size() + " name -> auth_id mappings");

        } catch (Exception e) {
            lastError = e.getClass().getSimpleName() + ": " + e.getMessage();
            System.err.println("Error loading sip_master mapping: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public String getLastError() {
        return lastError;
    }

    public int getLastQueryCount() {
        return lastQueryCount;
    }

    /**
     * Reload mapping from database (can be called via API)
     */
    public void reloadMapping() {
        callerIdToAuthIdMap.clear();
        srNumberToAuthIdMap.clear();
        agentNameToAuthIdMap.clear();
        lastError = null;
        lastQueryCount = 0;
        loadMappingFromDatabase();
    }

    public Integer getAuthIdByCallerId(String callerId) {
        return callerIdToAuthIdMap.get(callerId);
    }

    public void setSrNumberMapping(String srNumber, int authId) {
        srNumberToAuthIdMap.put(srNumber, authId);
    }

    public void setAgentNameMapping(String agentName, int authId) {
        agentNameToAuthIdMap.put(agentName.toLowerCase(), authId);
    }

    public Integer getAuthIdBySrNumber(String srNumber) {
        return srNumberToAuthIdMap.get(srNumber);
    }

    public Integer getAuthIdByAgentName(String agentName) {
        // Try exact match
        Integer authId = agentNameToAuthIdMap.get(agentName.toLowerCase());
        if (authId != null) return authId;

        // Try partial match
        for (Map.Entry<String, Integer> entry : agentNameToAuthIdMap.entrySet()) {
            if (agentName.toLowerCase().contains(entry.getKey()) || entry.getKey().contains(agentName.toLowerCase())) {
                return entry.getValue();
            }
        }
        return null;
    }

    public Map<String, Integer> getSrNumberMapping() {
        return srNumberToAuthIdMap;
    }

    public Map<String, Integer> getAgentNameMapping() {
        return agentNameToAuthIdMap;
    }

    public Map<String, Integer> getCallerIdMapping() {
        return callerIdToAuthIdMap;
    }

    public void clearMappings() {
        srNumberToAuthIdMap.clear();
        agentNameToAuthIdMap.clear();
    }

    public void updateStatus(int authId, String srNumber, String agentName, String agentStatus, String timeInStatus, String customerNumber) {
        AgentStatus status = new AgentStatus(authId, srNumber, agentName, agentStatus, timeInStatus, customerNumber);
        agentStatusMap.put(authId, status);
    }

    public AgentStatus getStatusByAuthId(int authId) {
        return agentStatusMap.get(authId);
    }

    public Map<Integer, AgentStatus> getAllStatusMap() {
        return agentStatusMap;
    }

    public List<AgentStatus> getAllStatuses() {
        return new ArrayList<>(agentStatusMap.values());
    }

    public void clearAll() {
        agentStatusMap.clear();
    }

    // Inner class to hold agent status
    public static class AgentStatus {
        private int authId;
        private String srNumber;
        private String agentName;
        private String agentStatus;
        private String timeInStatus;
        private String customerNumber;
        private LocalDateTime lastUpdated;

        public AgentStatus() {
        }

        public AgentStatus(int authId, String srNumber, String agentName, String agentStatus, String timeInStatus, String customerNumber) {
            this.authId = authId;
            this.srNumber = srNumber;
            this.agentName = agentName;
            this.agentStatus = agentStatus;
            this.timeInStatus = timeInStatus;
            this.customerNumber = customerNumber;
            this.lastUpdated = LocalDateTime.now();
        }

        public int getAuthId() {
            return authId;
        }

        public void setAuthId(int authId) {
            this.authId = authId;
        }

        public String getSrNumber() {
            return srNumber;
        }

        public void setSrNumber(String srNumber) {
            this.srNumber = srNumber;
        }

        public String getAgentName() {
            return agentName;
        }

        public void setAgentName(String agentName) {
            this.agentName = agentName;
        }

        public String getAgentStatus() {
            return agentStatus;
        }

        public void setAgentStatus(String agentStatus) {
            this.agentStatus = agentStatus;
        }

        public String getTimeInStatus() {
            return timeInStatus;
        }

        public void setTimeInStatus(String timeInStatus) {
            this.timeInStatus = timeInStatus;
        }

        public String getCustomerNumber() {
            return customerNumber;
        }

        public void setCustomerNumber(String customerNumber) {
            this.customerNumber = customerNumber;
        }

        public LocalDateTime getLastUpdated() {
            return lastUpdated;
        }

        public void setLastUpdated(LocalDateTime lastUpdated) {
            this.lastUpdated = lastUpdated;
        }
    }
}