package com.okithaki.autoapp;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.net.Uri;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import androidx.core.app.NotificationCompat;
import androidx.core.app.Person;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import org.json.JSONObject;
import org.json.JSONArray;

public class OkIthakiFirebaseMessagingService extends FirebaseMessagingService {
    private static final String PREFS = "ok_ithaki_prefs";

    private boolean englishUiV249466() {
        try { return "en".equals(getSharedPreferences(PREFS, MODE_PRIVATE).getString("ok_ui_language", "el")); }
        catch (Exception ignored) { return false; }
    }

    private String memberFallbackV249466() { return englishUiV249466() ? "Member" : "Μέλος"; }

    @Override public void onNewToken(String token) {
        if (TorIntegrationV249435.isRequested(this)) { getSharedPreferences(PREFS, MODE_PRIVATE).edit().putString("ok_fcm_token", "").apply(); return; }
        getSharedPreferences(PREFS, MODE_PRIVATE).edit().putString("ok_fcm_token", token == null ? "" : token).apply();
        registerTokenIfPossible(token);
    }

    private void registerTokenIfPossible(String token) {
        if (TorIntegrationV249435.isRequested(this)) return;
        try {
            if (token == null || token.trim().isEmpty()) return;
            final android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
            final String room = sp.getString("ok_fcm_room", "ithaki-phone-test");
            final String device = sp.getString("ok_fcm_device", "");
            final String nick = sp.getString("ok_fcm_nickname", "");
            final String base = sp.getString("ok_fcm_server", "https://ok-ithaki.gr");
            if (device == null || device.trim().isEmpty()) return;
            new Thread(() -> {
                HttpURLConnection conn = null;
                try {
                    URL url = new URL(base.replaceAll("/+$", "") + "/api/push/fcm/register");
                    conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("POST");
                    conn.setConnectTimeout(7000); conn.setReadTimeout(7000); conn.setDoOutput(true);
                    conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
                    JSONObject o = new JSONObject();
                    o.put("room_id", room); o.put("device_id", device); o.put("nickname", nick);
                    o.put("token", token); o.put("platform", "android"); o.put("source", "firebase-onnewtoken-v249425");
                    byte[] bytes = o.toString().getBytes(StandardCharsets.UTF_8);
                    OutputStream os = conn.getOutputStream(); os.write(bytes); os.close();
                    try { conn.getResponseCode(); } catch (Exception ignored) { }
                } catch (Exception ignored) { } finally { try { if (conn != null) conn.disconnect(); } catch (Exception ignored) { } }
            }).start();
        } catch (Exception ignored) { }
    }

    @Override public void onMessageReceived(RemoteMessage remoteMessage) {
        if (TorIntegrationV249435.isRequested(this)) return;
        Map<String,String> incoming = remoteMessage.getData();
        Map<String,String> data = new HashMap<>();
        if (incoming != null) data.putAll(incoming);
        String kind = safe(data.get("kind"));
        recordFcmDiagnosticR10F42("received", kind, data, "");
        boolean secureTransportV249435 = "secure_message_wake".equals(kind) || "secure_call_wake".equals(kind) || "communication_message_wake".equals(kind);
        if (secureTransportV249435) data.put("secure_transport_v249435", "1");
        String dedupeBase = safe(data.get("event_id"));
        if (dedupeBase.trim().isEmpty()) dedupeBase = safe(data.get("message_id"));
        if (dedupeBase.trim().isEmpty()) dedupeBase = safe(data.get("session_id"));
        if (dedupeBase.trim().isEmpty()) dedupeBase = safe(data.get("notification_id"));
        String dedupeKey = kind + ":" + dedupeBase;
        if (!dedupeBase.trim().isEmpty() && duplicateEventV249435(dedupeKey)) { recordFcmDiagnosticR10F42("suppressed", kind, data, "duplicate"); return; }
        String sessionId = safe(data.get("session_id"));
        if ("call_cancel".equals(kind) || "call_end".equals(kind) || "call_answered".equals(kind) || "call_rejected".equals(kind)) {
            cancelCallNotification(sessionId);
            return;
        }
        if (suppressClosedPushV249258(kind)) return;
        boolean enV249463 = englishUiV249466();
        String title = "OK ITHAKI";
        String body = enV249463 ? "New message" : "Νέο μήνυμα";
        if ("secure_message_wake".equals(kind) || "secure_call_wake".equals(kind) || "communication_message_wake".equals(kind)) {
            boolean completeR10F42 = "1".equals(safe(data.get("payload_complete_r10f42")))
                    && (!("secure_call_wake".equals(kind)) || !safe(data.get("session_id")).isEmpty());
            if (completeR10F42) {
                String resolved = safe(data.get("resolved_kind"));
                if (resolved.isEmpty()) resolved = "secure_call_wake".equals(kind) ? ("voice".equals(safe(data.get("call_type"))) ? "voice_call" : "video_call") : "message";
                data.put("kind", resolved);
                kind = resolved;
            } else {
                Map<String,String> hydrated = hydrateSecureWakeV249389(data);
                if (hydrated != null) { data.putAll(hydrated); kind = safe(data.get("kind")); }
            }
            if (!completeR10F42 && (data.get("session_id") == null || safe(data.get("session_id")).isEmpty()) && "secure_call_wake".equals(safe(incoming == null ? "" : incoming.get("kind")))) {
                data.put("kind", "voice_call");
                data.put("call_type", "voice");
                data.put("peer_name", enV249463 ? "Accepted friend" : "Αποδεκμένος φίλος");
                data.put("title", enV249463 ? "OK ITHAKI — secure call" : "OK ITHAKI — ασφαλής κλήση");
                data.put("body", enV249463 ? "An accepted friend is calling you" : "Αποδεκμένος φίλος σε καλεί");
            } else if (!completeR10F42 && ("secure_message_wake".equals(safe(incoming == null ? "" : incoming.get("kind"))) || "communication_message_wake".equals(safe(incoming == null ? "" : incoming.get("kind"))))) {
                data.put("kind", "message");
                data.put("sender_name", enV249463 ? "Accepted friend" : "Αποδεκμένος φίλος");
                data.put("title", enV249463 ? "OK ITHAKI — secure message" : "OK ITHAKI — ασφαλές μήνυμα");
                data.put("body", enV249463 ? "New secure message" : "Νέο ασφαλές μήνυμα");
            }
            kind = safe(data.get("kind"));
        }
        if (remoteMessage.getNotification() != null) {
            if (remoteMessage.getNotification().getTitle() != null) title = remoteMessage.getNotification().getTitle();
            if (remoteMessage.getNotification().getBody() != null) body = remoteMessage.getNotification().getBody();
        }
        if ("message".equals(kind)) {
            String peer = safe(data.get("peer_id"));
            if (peer.trim().isEmpty()) peer = safe(data.get("sender_id"));
            if (peer.trim().isEmpty()) peer = safe(data.get("from_id"));
            if (!peer.trim().isEmpty()) {
                data.put("peer_id", peer); data.put("sender_id", peer); data.put("from_id", peer);
                data.put("direct_open_dm", "1");
                data.put("open_messages", "1");
                String mid = safe(data.get("message_id"));
                data.put("url", "https://ok-ithaki.gr/?kind=message&open_messages=1&direct_open_dm=1&dm=" + encV249389(peer) + (mid.trim().isEmpty() ? "" : "&message_id=" + encV249389(mid)));
            }
        }
        showNotification(title, body, data);
    }

    private void recordFcmDiagnosticR10F42(String stage, String kind, Map<String,String> data, String reason) {
        try {
            android.content.SharedPreferences.Editor e = getSharedPreferences(PREFS, MODE_PRIVATE).edit();
            e.putLong("r10f42_last_fcm_at", System.currentTimeMillis());
            e.putString("r10f42_last_fcm_stage", safe(stage));
            e.putString("r10f42_last_fcm_kind", safe(kind));
            e.putString("r10f42_last_fcm_reason", safe(reason));
            if (data != null) {
                e.putString("r10f42_last_fcm_event_id", safe(data.get("event_id")));
                e.putString("r10f42_last_fcm_message_id", safe(data.get("message_id")));
                e.putString("r10f42_last_fcm_session_id", safe(data.get("session_id")));
                e.putString("r10f42_last_fcm_peer_id", safe(data.get("peer_id")));
                e.putBoolean("r10f42_last_payload_complete", "1".equals(safe(data.get("payload_complete_r10f42"))));
            }
            e.apply();
        } catch (Exception ignored) { }
    }

    private boolean duplicateEventV249435(String key) {
        try {
            android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
            long now = System.currentTimeMillis();
            JSONObject seen;
            try { seen = new JSONObject(sp.getString("fcm_seen_events_v249531", "{}")); }
            catch (Exception ignored) { seen = new JSONObject(); }
            java.util.Iterator<String> it = seen.keys();
            java.util.ArrayList<String> remove = new java.util.ArrayList<>();
            while (it.hasNext()) { String k = it.next(); if (now - seen.optLong(k, 0L) > 604800000L) remove.add(k); }
            for (String k : remove) seen.remove(k);
            boolean duplicate = seen.has(key) && now - seen.optLong(key, 0L) < 604800000L;
            seen.put(key, now);
            while (seen.length() > 160) {
                String oldest = null; long oldestAt = Long.MAX_VALUE;
                java.util.Iterator<String> keys = seen.keys();
                while (keys.hasNext()) { String k = keys.next(); long at = seen.optLong(k, 0L); if (at < oldestAt) { oldestAt = at; oldest = k; } }
                if (oldest == null) break; seen.remove(oldest);
            }
            sp.edit().putString("fcm_seen_events_v249531", seen.toString()).apply();
            return duplicate;
        } catch (Exception ignored) { return false; }
    }

    private String encV249389(String value) {
        try { return URLEncoder.encode(value == null ? "" : value, "UTF-8"); }
        catch (Exception ignored) { return ""; }
    }

    private Map<String,String> hydrateSecureWakeV249389(Map<String,String> data) {
        HttpURLConnection conn = null;
        try {
            android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
            String device = sp.getString("ok_fcm_device", "");
            String base = sp.getString("ok_fcm_server", "https://ok-ithaki.gr");
            String room = safe(data.get("room_id"));
            if (room.trim().isEmpty()) room = sp.getString("ok_fcm_room", "ithaki-phone-test");
            String eventId = safe(data.get("event_id"));
            String nonce = safe(data.get("nonce"));
            if (device.trim().isEmpty() || eventId.trim().isEmpty() || nonce.trim().isEmpty()) return null;
            boolean communicationWake = "communication_message_wake".equals(safe(data.get("kind")));
            String wakePath = communicationWake ? "/api/communication/wake_metadata_v249396" : "/api/secure/wake_metadata_v249389";
            String endpoint = base.replaceAll("/+$", "")
                    + wakePath + "?room_id=" + encV249389(room)
                    + "&recipient_id=" + encV249389(device)
                    + "&event_id=" + encV249389(eventId)
                    + "&nonce=" + encV249389(nonce);
            conn = (HttpURLConnection) new URL(endpoint).openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(4500);
            conn.setReadTimeout(4500);
            conn.setRequestProperty("Accept", "application/json");
            int code = conn.getResponseCode();
            if (code < 200 || code >= 300) return null;
            InputStream in = conn.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int read;
            while ((read = in.read(buffer)) >= 0 && out.size() < 1_000_000) out.write(buffer, 0, read);
            in.close();
            JSONObject json = new JSONObject(out.toString("UTF-8"));
            if (!json.optBoolean("ok", false) || !json.optBoolean("friend_accepted", false)) return null;
            Map<String,String> result = new HashMap<>();
            String eventKind = json.optString("event_kind", "message");
            String senderId = json.optString("sender_id", "");
            boolean enV249463 = englishUiV249466();
            String senderName = json.optString("sender_name", enV249463 ? "Member" : "Μέλος");
            String senderAvatar = json.optString("sender_avatar", "");
            result.put("peer_id", senderId);
            result.put("sender_id", senderId);
            result.put("sender_name", senderName);
            result.put("peer_name", senderName);
            result.put("sender_avatar", senderAvatar);
            result.put("channel", json.optString("channel", ""));
            if ("call".equals(eventKind)) {
                String callType = "voice".equals(json.optString("call_type", "")) ? "voice" : "video";
                result.put("kind", "voice".equals(callType) ? "voice_call" : "video_call");
                result.put("action", "incoming_call");
                result.put("call_type", callType);
                result.put("session_id", json.optString("session_id", ""));
                result.put("title", "voice".equals(callType)
                        ? (enV249463 ? "OK ITHAKI — secure voice call" : "OK ITHAKI — ασφαλής φωνητική κλήση")
                        : (enV249463 ? "OK ITHAKI — secure video call" : "OK ITHAKI — ασφαλής βιντεοκλήση"));
                result.put("body", senderName + (enV249463 ? " is calling you" : " σε καλεί"));
            } else {
                result.put("kind", "message");
                result.put("message_id", eventId);
                String securityMode = json.optString("security_mode", "full_e2ee");
                result.put("security_mode", securityMode);
                if ("no_encryption".equals(securityMode)) result.put("title", enV249463 ? "OK ITHAKI — new message" : "OK ITHAKI — νέο μήνυμα");
                else if ("standard_aes".equals(securityMode)) result.put("title", enV249463 ? "OK ITHAKI — encrypted message" : "OK ITHAKI — κρυπτογραφημένο μήνυμα");
                else result.put("title", enV249463 ? "OK ITHAKI — secure message" : "OK ITHAKI — ασφαλές μήνυμα");
                result.put("body", senderName + (enV249463 ? " sent you a new message" : " σου έστειλε νέο μήνυμα"));
            }
            return result;
        } catch (Exception ignored) {
            return null;
        } finally {
            try { if (conn != null) conn.disconnect(); } catch (Exception ignored) { }
        }
    }

    private String safe(String s) { return s == null ? "" : s; }

    private String pushModeV249258() {
        try { return getSharedPreferences(PREFS, MODE_PRIVATE).getString("ithaki_push_mode_v249258", "fcm_default"); }
        catch (Exception e) { return "fcm_default"; }
    }

    private boolean suppressClosedPushV249258(String kind) {
        String k = kind == null ? "" : kind.trim().toLowerCase(java.util.Locale.ROOT);
        // Calls and missed-call controls must always reach Android, even when ordinary
        // closed-app message notifications are disabled.
        if (k.contains("call") || "incoming_call".equals(k) || "secure_call_wake".equals(k)) return false;
        String m = pushModeV249258();
        return "no_closed".equals(m) || "open_app".equals(m);
    }

    private boolean isAppForegroundV249531() {
        try {
            android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
            return sp.getBoolean("ok_app_foreground_v249531", false)
                    && System.currentTimeMillis() - sp.getLong("ok_app_foreground_at_v249531", 0L) < 25000L;
        } catch (Exception ignored) { return false; }
    }

    private String niceNameV249258(Map<String,String> data) {
        if (data == null) return memberFallbackV249466();
        String n = safe(data.get("sender_name"));
        if (n.trim().isEmpty()) n = safe(data.get("peer_name"));
        if (n.trim().isEmpty()) n = safe(data.get("from_name"));
        if (n.trim().isEmpty()) n = memberFallbackV249466();
        return n.trim();
    }

    private void cancelCallNotification(String sessionId) {
        try {
            NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (nm != null) {
                int id = sessionId == null || sessionId.trim().isEmpty() ? 4916 : Math.abs(("call_" + sessionId).hashCode());
                nm.cancel(id);
                nm.cancel(4916);
                try {
                    Set<String> ids = getSharedPreferences(PREFS, MODE_PRIVATE).getStringSet("ok_active_call_notification_ids", null);
                    if (ids != null) for (String x : ids) { try { nm.cancel(Integer.parseInt(x)); } catch (Exception ignored) { } }
                    getSharedPreferences(PREFS, MODE_PRIVATE).edit().remove("ok_active_call_notification_ids").apply();
                } catch (Exception ignored) { }
            }
        } catch (Exception ignored) { }
    }

    private Bitmap loadSecureAvatarV249389(String avatar) {
        if (avatar == null || avatar.trim().isEmpty()) return null;
        try {
            String value = avatar.trim();
            if (value.startsWith("data:image/")) {
                int comma = value.indexOf(',');
                if (comma > 0) {
                    byte[] bytes = android.util.Base64.decode(value.substring(comma + 1), android.util.Base64.DEFAULT);
                    return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                }
            }
            if (value.startsWith("https://") || value.startsWith("http://")) {
                HttpURLConnection conn = (HttpURLConnection) new URL(value).openConnection();
                conn.setConnectTimeout(3500);
                conn.setReadTimeout(3500);
                conn.setInstanceFollowRedirects(true);
                try {
                    if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) {
                        return BitmapFactory.decodeStream(conn.getInputStream());
                    }
                } finally {
                    conn.disconnect();
                }
            }
        } catch (Exception ignored) { }
        return null;
    }

    private boolean legacyCompanionTextV249466(String value) {
        String v = value == null ? "" : value.toLowerCase(java.util.Locale.ROOT);
        return v.contains("αθην") || v.contains("athena") || v.contains("athina")
                || v.contains("σωκρατάκ") || v.contains("sokrataki") || v.contains("socrates companion");
    }

    private JSONObject notificationPreferencesR10F40() {
        try { return new JSONObject(getSharedPreferences(PREFS, MODE_PRIVATE).getString("ok_notification_preferences_r10f40", "{}")); }
        catch (Exception ignored) { return new JSONObject(); }
    }

    private String notificationCategoryR10F40(String kind) {
        String k = safe(kind).toLowerCase(java.util.Locale.ROOT);
        if (k.contains("call")) return "calls";
        if (k.contains("message") || k.equals("dm") || k.contains("chat")) return "messages";
        if (k.contains("friend") || k.contains("contact") || k.contains("request")) return "friends";
        if (k.contains("like") || k.contains("reaction") || k.contains("heart")) return "reactions";
        if (k.contains("mention")) return "mentions";
        if (k.contains("follow")) return "followers";
        if (k.contains("reply")) return "replies";
        if (k.contains("comment")) return "comments";
        if (k.contains("post") || k.contains("publication") || k.contains("video") || k.contains("photo") || k.contains("story")) return "posts";
        if (k.contains("community") || k.contains("room") || k.contains("space")) return "communities";
        if (k.contains("security") || k.contains("admin") || k.contains("legal") || k.contains("report") || k.contains("warning") || k.contains("ban")) return "security";
        return "system";
    }

    private boolean notificationCategoryEnabledR10F40(JSONObject prefs, String kind) {
        try {
            JSONObject categories = prefs.optJSONObject("categories");
            return categories == null || categories.optBoolean(notificationCategoryR10F40(kind), true);
        } catch (Exception ignored) { return true; }
    }

    private boolean quietNowR10F40(JSONObject prefs) {
        try {
            if (!prefs.optBoolean("quiet", false)) return false;
            String[] a = prefs.optString("quietStart", "22:30").split(":");
            String[] b = prefs.optString("quietEnd", "07:30").split(":");
            int start = Integer.parseInt(a[0]) * 60 + Integer.parseInt(a[1]);
            int end = Integer.parseInt(b[0]) * 60 + Integer.parseInt(b[1]);
            java.util.Calendar c = java.util.Calendar.getInstance();
            int current = c.get(java.util.Calendar.HOUR_OF_DAY) * 60 + c.get(java.util.Calendar.MINUTE);
            return start == end || (start < end ? current >= start && current < end : current >= start || current < end);
        } catch (Exception ignored) { return false; }
    }

    private void showNotification(String title, String body, Map<String,String> data) {
        boolean en = englishUiV249466();
        String kind = data == null ? "" : safe(data.get("kind"));
        boolean encryptedTransportV249435 = data != null && "1".equals(safe(data.get("secure_transport_v249435")));
        String securityModeV249435 = data == null ? "" : safe(data.get("security_mode"));
        boolean privateEncryptedV249435 = encryptedTransportV249435 && !"no_encryption".equals(securityModeV249435);
        String sessionId = data == null ? "" : safe(data.get("session_id"));
        if (suppressClosedPushV249258(kind)) return;
        String action = data == null ? "" : safe(data.get("action"));
        String callType = data == null ? "" : safe(data.get("call_type"));
        String dataTitle = data == null ? "" : safe(data.get("title"));
        String dataBody = data == null ? "" : safe(data.get("body"));
        String peerName = data == null ? "" : safe(data.get("peer_name"));
        boolean isLiveCall = ("voice_call".equals(kind) || "video_call".equals(kind) || "call_invite".equals(kind) || "incoming_call".equals(action));
        boolean isMissedCall = "missed_call".equals(kind);
        boolean isCall = isLiveCall;
        android.content.SharedPreferences notificationPrefsV249525=getSharedPreferences(PREFS,MODE_PRIVATE);
        JSONObject notificationPrefsR10F40=notificationPreferencesR10F40();
        boolean notificationMasterV249525=notificationPrefsV249525.getBoolean("ok_notifications_enabled_v249525",true);
        boolean notificationSoundV249525=notificationPrefsV249525.getBoolean("ok_notification_sound_v249525",true);
        boolean notificationVibrationR10F40=notificationPrefsV249525.getBoolean("ok_notification_vibration_r10f40",true);
        boolean appForegroundV249531=isAppForegroundV249531();
        if(!isCall && !notificationMasterV249525) { recordFcmDiagnosticR10F42("suppressed",kind,data,"master_disabled"); return; }
        if(!isCall && !notificationCategoryEnabledR10F40(notificationPrefsR10F40,kind)) { recordFcmDiagnosticR10F42("suppressed",kind,data,"category_disabled"); return; }
        boolean quietR10F40=quietNowR10F40(notificationPrefsR10F40);
        boolean urgentR10F40=isCall || "security".equals(notificationCategoryR10F40(kind));
        boolean allowUrgentR10F40=notificationPrefsR10F40.optBoolean("urgentDuringQuiet",true);
        if(quietR10F40 && !(urgentR10F40 && allowUrgentR10F40)){notificationSoundV249525=false;notificationVibrationR10F40=false;}
        // In the foreground, the WebSocket/UI is the single message owner. FCM remains
        // the owner for live calls so a call cannot be missed between poll cycles.
        if(appForegroundV249531 && !isCall) { recordFcmDiagnosticR10F42("suppressed",kind,data,"foreground_ui_owner"); return; }

        if (!dataTitle.trim().isEmpty()) title = dataTitle.trim();
        if (!dataBody.trim().isEmpty()) body = dataBody.trim();
        // V249466: never surface legacy Athena/Sokrataki push text. Bil wisdom is handled
        // only by the current frontend and is not duplicated as a system notification.
        if (legacyCompanionTextV249466(title) || legacyCompanionTextV249466(body)) return;

        String person = peerName == null || peerName.trim().isEmpty() ? memberFallbackV249466() : peerName.trim();
        if (isLiveCall) {
            boolean voice = "voice".equals(callType) || "voice_call".equals(kind);
            title = voice
                    ? (en ? "OK ITHAKI — voice call" : "OK ITHAKI — φωνητική κλήση")
                    : (en ? "OK ITHAKI — video call" : "OK ITHAKI — βιντεοκλήση");
            body = person + (en ? " is calling you" : " σε καλεί");
        } else if (isMissedCall) {
            title = en ? "OK ITHAKI — missed call" : "OK ITHAKI — αναπάντητη κλήση";
            body = en ? "You have a missed call in ITHAKI" : "Έχεις αναπάντητη κλήση στην ΙΘΑΚΗ";
        } else if ("message".equals(kind)) {
            title = en ? "OK ITHAKI — new message" : "OK ITHAKI — νέο μήνυμα";
            body = niceNameV249258(data) + (en ? " sent you a message" : " σου έστειλε μήνυμα");
        } else if ("like".equals(kind) || "post_like".equals(kind)) {
            title = en ? "OK ITHAKI — new reaction" : "OK ITHAKI — νέα αντίδραση";
            body = niceNameV249258(data) + (en ? " liked your post" : " έκανε like στη δημοσίευσή σου");
        } else if ("member_online".equals(kind) || "friend_online".equals(kind)) {
            title = en ? "OK ITHAKI — friend online" : "OK ITHAKI — φίλος ενεργός";
            body = en ? "Your friend " + niceNameV249258(data) + " is now online" : "Μόλις μπήκε μέσα ο φίλος σου, " + niceNameV249258(data);
        } else if ("new_post".equals(kind) || "new_video".equals(kind) || "video_post".equals(kind) || "followed_post".equals(kind)) {
            title = en ? "OK ITHAKI — new post" : "OK ITHAKI — νέα δημοσίευση";
            body = niceNameV249258(data) + (en ? ", whom you follow, published a new post" : ", που παρακολουθείς, έκανε νέα δημοσίευση");
        } else if ("friend_request".equals(kind) || "contact".equals(kind)) {
            title = en ? "OK ITHAKI — friend request" : "OK ITHAKI — αίτημα φιλίας";
            body = niceNameV249258(data) + (en ? " sent you a friend request" : " σου έστειλε αίτημα φιλίας");
        } else if ("friend_accepted".equals(kind) || "friend_accept".equals(kind) || "friendship_accepted".equals(kind)) {
            title = en ? "OK ITHAKI — friendship accepted" : "OK ITHAKI — αποδοχή φιλίας";
            body = niceNameV249258(data) + (en ? " accepted your friend request" : " αποδέχτηκε το αίτημα φιλίας σου");
        } else if ("follow".equals(kind) || "new_follower".equals(kind)) {
            title = en ? "OK ITHAKI — new follower" : "OK ITHAKI — νέος ακόλουθος";
            body = niceNameV249258(data) + (en ? " started following you" : " άρχισε να σε ακολουθεί");
        } else if ("comment".equals(kind) || "post_comment".equals(kind)) {
            title = en ? "OK ITHAKI — new comment" : "OK ITHAKI — νέο σχόλιο";
            body = niceNameV249258(data) + (en ? " commented on your post" : " σχολίασε τη δημοσίευσή σου");
        } else if ("reply".equals(kind) || "comment_reply".equals(kind)) {
            title = en ? "OK ITHAKI — new reply" : "OK ITHAKI — νέα απάντηση";
            body = niceNameV249258(data) + (en ? " replied to you" : " σου απάντησε");
        } else if ("mention".equals(kind)) {
            title = en ? "OK ITHAKI — mention" : "OK ITHAKI — αναφορά";
            body = niceNameV249258(data) + (en ? " mentioned you" : " σε ανέφερε");
        } else if ("poll".equals(kind)) {
            title = en ? "OK ITHAKI — poll update" : "OK ITHAKI — ενημέρωση ψηφοφορίας";
            body = en ? "There is a new poll update" : "Υπάρχει νέα ενημέρωση ψηφοφορίας";
        } else if ("file".equals(kind) || "photo".equals(kind) || "video".equals(kind) || "audio".equals(kind)) {
            title = en ? "OK ITHAKI — new attachment" : "OK ITHAKI — νέο συνημμένο";
            body = niceNameV249258(data) + (en ? " sent you a file" : " σου έστειλε αρχείο");
        }
        if (privateEncryptedV249435 && !isCall) {
            title = en ? "OK ITHAKI — encrypted message" : "OK ITHAKI — κρυπτογραφημένο μήνυμα";
            body = en ? "New private message. Open ITHAKI to decrypt it." : "Νέο ιδιωτικό μήνυμα. Άνοιξε την ΙΘΑΚΗ για αποκρυπτογράφηση.";
        }

        String callKey = "";
        if (isCall) {
            try {
                String collapse = data == null ? "" : safe(data.get("collapse_key"));
                String peerId = data == null ? "" : safe(data.get("peer_id"));
                callKey = !collapse.trim().isEmpty() ? collapse.trim() : (!sessionId.trim().isEmpty() ? sessionId.trim() : (peerId + "_" + callType + "_" + kind));
                android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
                String last = sp.getString("ok_last_call_key_v249259", "");
                long lastAt = sp.getLong("ok_last_call_key_at_v249259", 0L);
                long now = System.currentTimeMillis();
                String sharedSid = sp.getString("ok_call_alert_session_v249531", "");
                long sharedAt = sp.getLong("ok_call_alert_at_v249531", 0L);
                if ((callKey.equals(last) && now - lastAt < 120000L) || (callKey.equals(sharedSid) && now - sharedAt < 120000L)) return;
                sp.edit()
                  .putString("ok_last_call_key_v249259", callKey)
                  .putLong("ok_last_call_key_at_v249259", now)
                  .putString("ok_call_alert_session_v249531", callKey)
                  .putLong("ok_call_alert_at_v249531", now)
                  .apply();
            } catch (Exception ignored) { }
        }

        String preferenceSuffixR10F40 = notificationSoundV249525 ? (notificationVibrationR10F40 ? "sound_vibrate" : "sound_only") : (notificationVibrationR10F40 ? "silent_vibrate" : "silent");
        String channelId = isCall ? "ok_ithaki_fcm_calls_v249531" : (privateEncryptedV249435 ? "ok_ithaki_fcm_secure_r10f40_" + preferenceSuffixR10F40 : "ok_ithaki_fcm_messages_r10f40_" + preferenceSuffixR10F40);
        Uri soundUri = isCall ? RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE) : RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= 26 && nm != null) {
            String channelName = isCall
                    ? (en ? "OK ITHAKI Calls" : "OK ITHAKI Κλήσεις")
                    : (privateEncryptedV249435
                        ? (en ? "OK ITHAKI Encrypted" : "OK ITHAKI Κρυπτογραφημένα")
                        : (en ? "OK ITHAKI Messages" : "OK ITHAKI Μηνύματα"));
            NotificationChannel ch = new NotificationChannel(channelId, channelName, isCall ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT);
            ch.enableVibration(isCall || notificationVibrationR10F40);
            ch.setLockscreenVisibility(privateEncryptedV249435 ? android.app.Notification.VISIBILITY_PRIVATE : android.app.Notification.VISIBILITY_PUBLIC);
            try {
                AudioAttributes attrs = new AudioAttributes.Builder()
                    .setUsage(isCall ? AudioAttributes.USAGE_NOTIFICATION_RINGTONE : AudioAttributes.USAGE_NOTIFICATION)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .build();
                if(isCall || notificationSoundV249525) ch.setSound(soundUri, attrs); else ch.setSound(null,null);
            } catch (Exception ignored) { }
            nm.createNotificationChannel(ch);
        }

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        if (data != null) for (Map.Entry<String,String> e : data.entrySet()) intent.putExtra(e.getKey(), e.getValue());
        intent.putExtra("fcm_kind", kind);
        if (isCall) { intent.putExtra("call", "1"); intent.putExtra("open_video_call_immediately", "1"); } else if ("message".equals(kind)) { intent.putExtra("open_messages", "1"); intent.putExtra("direct_open_dm", "1"); }
        String messageIdV249509 = data == null ? "" : safe(data.get("message_id"));
        int requestCode = isCall && !sessionId.trim().isEmpty() ? Math.abs(("pi_" + sessionId).hashCode()) : (!messageIdV249509.trim().isEmpty() ? Math.abs(("pi_msg_" + messageIdV249509).hashCode()) : 2509);
        int flags = Build.VERSION.SDK_INT >= 23 ? (PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT) : PendingIntent.FLAG_UPDATE_CURRENT;
        PendingIntent pi = PendingIntent.getActivity(this, requestCode, intent, flags);
        android.content.SharedPreferences sp = getSharedPreferences(PREFS, MODE_PRIVATE);
        int badge = sp.getInt("ok_ithaki_unread_badge", 0);
        if (!isCall) {
            badge += 1;
            sp.edit().putInt("ok_ithaki_unread_badge", badge).apply();
        }
        String messageStableV249531 = !messageIdV249509.trim().isEmpty() ? messageIdV249509 : safe(data == null ? "" : data.get("event_id"));
        if (messageStableV249531.trim().isEmpty()) messageStableV249531 = safe(data == null ? "" : data.get("notification_id"));
        if (messageStableV249531.trim().isEmpty()) messageStableV249531 = kind + "|" + niceNameV249258(data) + "|" + body;
        int notificationId = isCall ? Math.abs(("call_" + (callKey == null || callKey.trim().isEmpty() ? sessionId : callKey)).hashCode()) : Math.abs(("msg_" + messageStableV249531).hashCode());
        if (isCall) {
            try {
                Set<String> ids = new HashSet<>();
                Set<String> oldIds = getSharedPreferences(PREFS, MODE_PRIVATE).getStringSet("ok_active_call_notification_ids", null);
                if (oldIds != null) ids.addAll(oldIds);
                ids.add(String.valueOf(notificationId)); ids.add("4916");
                getSharedPreferences(PREFS, MODE_PRIVATE).edit().putStringSet("ok_active_call_notification_ids", ids).apply();
            } catch (Exception ignored) { }
        }
        NotificationCompat.Builder b = new NotificationCompat.Builder(this, channelId)
            .setSmallIcon(android.R.drawable.ic_dialog_email)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(!isCall)
            .setOngoing(isCall)
            .setOnlyAlertOnce(true)
            .setPriority(isCall ? NotificationCompat.PRIORITY_MAX : NotificationCompat.PRIORITY_HIGH)
            .setCategory(isCall ? NotificationCompat.CATEGORY_CALL : NotificationCompat.CATEGORY_MESSAGE)
            .setDefaults(isCall ? 0 : (notificationSoundV249525 ? (NotificationCompat.DEFAULT_SOUND | NotificationCompat.DEFAULT_LIGHTS) : NotificationCompat.DEFAULT_LIGHTS))
            .setSound((isCall || notificationSoundV249525) ? soundUri : null)
            .setVibrate(isCall ? new long[]{0, 700, 350, 700, 350, 700} : (notificationVibrationR10F40 ? new long[]{0, 250, 120, 250} : new long[]{0L}))
            .setNumber(badge)
            .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
            .setVisibility(privateEncryptedV249435 ? NotificationCompat.VISIBILITY_PRIVATE : NotificationCompat.VISIBILITY_PUBLIC)
            .setContentIntent(pi);
        if (privateEncryptedV249435) {
            NotificationCompat.Builder publicBuilder = new NotificationCompat.Builder(this, channelId)
                    .setSmallIcon(android.R.drawable.ic_dialog_email)
                    .setContentTitle("OK ITHAKI")
                    .setContentText(en ? "New private message" : "Νέο ιδιωτικό μήνυμα")
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            b.setPublicVersion(publicBuilder.build());
        }
        if (isCall) {
            try {
                Intent answerIntent = new Intent(this, CallActionReceiverR10F42.class).setAction(CallActionReceiverR10F42.ACTION_ANSWER);
                Intent declineIntent = new Intent(this, CallActionReceiverR10F42.class).setAction(CallActionReceiverR10F42.ACTION_DECLINE);
                if (data != null) for (Map.Entry<String,String> e : data.entrySet()) { answerIntent.putExtra(e.getKey(),e.getValue()); declineIntent.putExtra(e.getKey(),e.getValue()); }
                answerIntent.putExtra("notification_id_int", notificationId);
                declineIntent.putExtra("notification_id_int", notificationId);
                int actionFlags = Build.VERSION.SDK_INT >= 23 ? (PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT) : PendingIntent.FLAG_UPDATE_CURRENT;
                PendingIntent answerPi = PendingIntent.getBroadcast(this, Math.abs(("answer_"+sessionId).hashCode()), answerIntent, actionFlags);
                PendingIntent declinePi = PendingIntent.getBroadcast(this, Math.abs(("decline_"+sessionId).hashCode()), declineIntent, actionFlags);
                Person caller = new Person.Builder().setName(person).setImportant(true).build();
                b.setStyle(NotificationCompat.CallStyle.forIncomingCall(caller, declinePi, answerPi));
                if (!appForegroundV249531) b.setFullScreenIntent(pi, true);
                b.setTimeoutAfter(90000L);
            } catch (Exception ignored) { }
        }
        if (nm != null) { nm.notify(notificationId, b.build()); recordFcmDiagnosticR10F42("notified",kind,data,""); }
    }
}
