package com.yourcompany.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.company.handanomaly.sdk.HandAnomalySdk;
import com.company.handanomaly.sdk.SecurityError;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.List;
import java.util.Map;

/**
 * 手部异常多分类算法 SDK 对接示例（RK3568 NPU · v3 · 10 类）。
 *
 * 客户只需 2 步：
 *   1) sdk.activate("ACT-XXXX-XXXX-XXXX");          // 仅首次（激活后本地缓存，离线可用）
 *   2) sdk.recognizeToJson(jpegBytes);              // 每次识别，返回 JSON 字符串
 *
 * 算法 10 类（见 SDK 常量）：
 *   整手框（放置判定用）：palm（手掌）、back（手背）
 *   异常框：ring（戒指）、nail_polish（美甲）、long_nail（长指甲）、wound（伤口）、
 *          glove（手套）、bandaid（创可贴）、watch（手表）、bracelet（手镯）
 */
public class HandAnomalyClient {

    private static final String TAG = "HandAnomalyClient";

    /** 我方下发的激活码（仅首次激活用；亦可走 ②设备激活 / ③申请 / ④快速码，详见手册） */
    private static final String ACTIVATION_CODE = "ACT-XXXX-XXXX-XXXX";

    private final HandAnomalySdk sdk;

    public HandAnomalyClient(Context context) {
        // 构造即加载内置资源：公网 HTTPS 授权地址、平台公钥、加密算法包（均构建时注入，无需配置）
        this.sdk = new HandAnomalySdk(context.getApplicationContext());
    }

    // ============================ 第 1 步：激活（仅首次） ============================

    /** 首次使用激活；成功后授权与解密密钥缓存到本地，之后无需联网。 */
    public void activateOnce() {
        // 先查本地是否已有有效授权（换机/清缓存才需重新激活）
        Map<String, Object> lic = sdk.checkLicense();
        boolean activated = Boolean.TRUE.equals(lic.get("activated"));
        if (activated) {
            Log.i(TAG, "已激活，无需重复激活：" + lic);
            return;
        }
        try {
            sdk.activate(ACTIVATION_CODE);
            Log.i(TAG, "激活成功。设备短码(deviceId)=" + sdk.deviceId()
                    + "，可向平台方报备该码以便排查。");
        } catch (SecurityError e) {
            Log.e(TAG, "激活失败：" + e.getMessage());
            throw e;
        }
    }

    // ============================ 第 2 步：识别 ============================

    /**
     * 方式 A（推荐，最省事）：直接拿 JSON 字符串。
     * @param jpegBytes 摄像头帧 / 图片的 JPEG 字节
     * @return JSON 数组，如 [{"label":"wound","score":0.93,"bbox":[412,233,86,74]}]；无异常返回 "[]"
     */
    public String detectToJson(byte[] jpegBytes) {
        return sdk.recognizeToJson(jpegBytes);
    }

    /**
     * 方式 B：拿结构化 List，自行处理。
     * @return 每个元素 { label:String, score:Double, bbox:float[4] (x,y,w,h) }
     */
    public List<Map<String, Object>> detect(byte[] jpegBytes) {
        return sdk.recognizeImageBytes(jpegBytes);
    }

    // ============================ 结果语义解析（10 类） ============================

    /** 整手框类别：出现即代表"手已放入取景框/检测区" */
    private static final String[] WHOLE_HAND = {"palm", "back"};
    /** 异常框类别 */
    private static final String[] ANOMALY = {
            "ring", "nail_polish", "long_nail", "wound",
            "glove", "bandaid", "watch", "bracelet"
    };

    /** 从 detectToJson 的结果中解析业务结论。 */
    public static Result interpret(String json) {
        Result r = new Result();
        try {
            JSONArray arr = new JSONArray(json);
            for (int i = 0; i < arr.length(); i++) {
                JSONObject o = arr.getJSONObject(i);
                String label = o.getString("label");
                double score = o.getDouble("score");
                JSONArray b = o.getJSONArray("bbox");
                float[] bbox = {(float) b.getDouble(0), (float) b.getDouble(1),
                                (float) b.getDouble(2), (float) b.getDouble(3)};
                if (isWholeHand(label)) {
                    r.handPlaced = true;
                    r.handLabel = label;
                } else if (isAnomaly(label)) {
                    r.anomalies.add(new Detection(label, score, bbox));
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "解析识别结果失败：" + e.getMessage());
        }
        return r;
    }

    private static boolean isWholeHand(String l) {
        for (String w : WHOLE_HAND) if (w.equals(l)) return true;
        return false;
    }
    private static boolean isAnomaly(String l) {
        for (String a : ANOMALY) if (a.equals(l)) return true;
        return false;
    }

    /** 识别结论 */
    public static class Result {
        public boolean handPlaced = false;       // 手是否已放入取景框
        public String handLabel = "";            // palm / back
        public java.util.List<Detection> anomalies = new java.util.ArrayList<>();
        public boolean hasAnomaly() { return !anomalies.isEmpty(); }
    }

    public static class Detection {
        public final String label;
        public final double score;
        public final float[] bbox;               // [x, y, w, h]（原图像素坐标）
        Detection(String label, double score, float[] bbox) {
            this.label = label; this.score = score; this.bbox = bbox;
        }
    }

    // ============================ 摄像头取帧（CameraX 示意） ============================
    // 下面给出把 CameraX 帧转成 JPEG 字节后送识别的最小示意。
    // 实际项目请按贵司 CameraX 集成方式取帧（ImageProxy → JPEG → byte[]）。

    /**
     * 把 Bitmap 编码为 JPEG 字节（演示用；生产建议直接用摄像头回调的 JPEG/ImageProxy）。
     */
    public static byte[] bitmapToJpegBytes(Bitmap bmp, int quality) {
        java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.JPEG, quality, os);
        return os.toByteArray();
    }

    public static Bitmap jpegBytesToBitmap(byte[] jpeg) {
        return BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length);
    }

    // ---- CameraX 取帧 → 识别 的最小骨架（放在 Activity/Fragment 中）----
    /*
    private void startDetect(HandAnomalyClient client, androidx.camera.core.ImageAnalysis analysis) {
        analysis.setAnalyzer(ContextCompat.getMainExecutor(this), imageProxy -> {
            try {
                // ImageProxy → JPEG bytes（具体实现依贵司封装；这里仅示意）
                byte[] jpeg = imageProxyToJpeg(imageProxy);
                String json = client.detectToJson(jpeg);
                Result res = HandAnomalyClient.interpret(json);
                if (res.handPlaced && res.hasAnomaly()) {
                    // 手已放好且检测到异常：弹窗/记录/拦截
                    Log.w(TAG, "检测到异常：" + res.anomalies);
                } else if (!res.handPlaced) {
                    Log.i(TAG, "未检测到手（请提示用户将手放入取景框）");
                }
            } finally {
                imageProxy.close();
            }
        });
    }
    */
}
