package kr.sblog.slimbudget;

import android.app.Notification;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;

import org.json.JSONObject;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * 카드사 결제 푸시 알림을 가로채 백엔드로 전달한다.
 * - 결제로 보이는 알림(금액+승인/결제/카드)만 전송 (개인정보 최소화)
 * - 인증 토큰은 Capacitor Preferences(SharedPreferences "CapacitorStorage")의 token 사용
 * - 백엔드가 파싱·중복제거·미확인 내역 생성
 */
public class CardNotifListenerService extends NotificationListenerService {

    private static final String API_URL = "https://app.sblog.kr/api/account/entries/notification";

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        try {
            if (sbn == null || sbn.getNotification() == null) return;
            Bundle ex = sbn.getNotification().extras;
            if (ex == null) return;

            CharSequence titleCs = ex.getCharSequence(Notification.EXTRA_TITLE);
            CharSequence textCs = ex.getCharSequence(Notification.EXTRA_TEXT);
            CharSequence bigCs = ex.getCharSequence(Notification.EXTRA_BIG_TEXT);

            String title = titleCs == null ? "" : titleCs.toString();
            String text = (bigCs != null ? bigCs : (textCs == null ? "" : textCs)).toString();

            if (!looksLikePayment(title + " " + text)) return;

            String token = getSharedPreferences("CapacitorStorage", MODE_PRIVATE)
                    .getString("token", null);
            if (token == null || token.isEmpty()) return;

            final String pkg = sbn.getPackageName();
            new Thread(() -> post(pkg, title, text, token)).start();
        } catch (Exception ignore) {
            // 알림 처리 실패는 무시 (앱 동작에 영향 없도록)
        }
    }

    /**
     * 결제/이체 알림 후보 판별: 금액(####원) + 승인/결제/출금/입금/이체/취소 키워드.
     * '카드'는 광고에도 흔해 제외. 강한 신호 없이 광고성 표현이 있으면 제외.
     * (1차 필터 — 최종 판별/분류는 백엔드 파서)
     */
    private boolean looksLikePayment(String s) {
        boolean money = s.matches("(?s).*\\d[\\d,]{2,}\\s*원.*");
        boolean kw = s.contains("승인") || s.contains("결제") || s.contains("출금")
                || s.contains("입금") || s.contains("이체") || s.contains("송금");
        if (!money || !kw) return false;
        boolean strong = s.contains("승인") || s.contains("출금") || s.contains("입금")
                || s.contains("이체") || s.contains("송금") || s.contains("취소") || s.contains("환불");
        boolean adLike = s.matches("(?s).*(이벤트|광고|혜택|쿠폰|할인|적립|포인트|캐시백|마일리지|리워드|당첨|응모|추첨|프로모션|배너|무료|증정|모집).*");
        return strong || !adLike;
    }

    private void post(String pkg, String title, String text, String token) {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(API_URL);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "Bearer " + token);
            conn.setConnectTimeout(8000);
            conn.setReadTimeout(8000);
            conn.setDoOutput(true);

            JSONObject body = new JSONObject();
            body.put("app", pkg);
            body.put("title", title);
            body.put("text", text);

            try (OutputStream os = conn.getOutputStream()) {
                os.write(body.toString().getBytes(StandardCharsets.UTF_8));
            }
            conn.getResponseCode(); // 요청 전송 (응답은 무시)
        } catch (Exception ignore) {
            // 네트워크 실패는 무시
        } finally {
            if (conn != null) conn.disconnect();
        }
    }
}
