// This is a placeholder for TikTok-Live-Connector integration.
// The actual implementation will require the TikTok-Live-Connector JAR in the lib folder.
// At test time, you will be provided with the download link and instructions.

import java.util.Map;

@SuppressWarnings("unchecked")
public class TikTokEventListener {
    private final Map<String, Object> config;
    private final Map<String, Object> format;
    private final WebSocketServerApp wsServer;

    public TikTokEventListener(Map<String, Object> config, Map<String, Object> format, WebSocketServerApp wsServer) {
        this.config = config;
        this.format = format;
        this.wsServer = wsServer;
    }

    private String formatEvent(String eventType, String target, Map<String, String> vars) {
        try {
            Map<String, Object> events = (Map<String, Object>) format.get("events");
            Map<String, Object> event = (Map<String, Object>) events.get(eventType);
            Map<String, Object> fmt = (Map<String, Object>) event.get(target);
            String text = (String) ((Map<String, Object>) fmt).get("text");
            for (Map.Entry<String, String> entry : vars.entrySet()) {
                text = text.replace("$" + entry.getKey(), entry.getValue());
            }
            return text;
        } catch (Exception e) {
            return "[Format error]";
        }
    }

    private void output(String eventType, Map<String, String> vars, String filePath) {
        String date = java.time.LocalDate.now().toString();
        String time = java.time.LocalTime.now().withNano(0).toString();
        vars.put("date", date);
        vars.put("time", time);

        // Console output
        String cliMsg = formatEvent(eventType, "cli_format", vars);
        System.out.println(cliMsg);

        // File output
        if (filePath != null && !filePath.isEmpty()) {
            String fileMsg = formatEvent(eventType, "file_format", vars);
            EventLogger.logToFile(filePath, fileMsg);
        }

        // WebSocket output
        if (wsServer != null) {
            wsServer.broadcastEvent(cliMsg);
        }
    }

    public void onFollow(String userInfo) {
        Map<String, String> vars = new java.util.HashMap<>();
        vars.put("userinfo", userInfo);
        String filePath = getOutputPath("follow");
        output("follow", vars, filePath);
    }

    public void onLike(String userInfo, int amount) {
        Map<String, String> vars = new java.util.HashMap<>();
        vars.put("userinfo", userInfo);
        vars.put("amount", String.valueOf(amount));
        String filePath = getOutputPath("likes");
        output("likes", vars, filePath);
    }

    public void onShare(String userInfo) {
        Map<String, String> vars = new java.util.HashMap<>();
        vars.put("userinfo", userInfo);
        String filePath = getOutputPath("shares");
        output("shares", vars, filePath);
    }

    public void onGift(String userInfo, String giftName, int amount) {
        Map<String, String> vars = new java.util.HashMap<>();
        vars.put("userinfo", userInfo);
        vars.put("gift_name", giftName);
        vars.put("amount", String.valueOf(amount));
        String filePath = getOutputPath("gifts");
        output("gifts", vars, filePath);
    }

    public void onChat(String userInfo, String message) {
        Map<String, String> vars = new java.util.HashMap<>();
        vars.put("userinfo", userInfo);
        vars.put("msg", message);
        String filePath = getOutputPath("chat");
        output("chat", vars, filePath);
    }

    private String getOutputPath(String eventType) {
        try {
            Map<String, Object> events = (Map<String, Object>) config.get("events");
            Map<String, Object> event = (Map<String, Object>) events.get(eventType);
            Map<String, Object> fileEnable = (Map<String, Object>) event.get("file_enable");
            if (fileEnable != null && fileEnable.containsKey("output_path")) {
                return (String) fileEnable.get("output_path");
            }
        } catch (Exception ignored) {}
        return null;
    }
}
