package com.app.duck.util;


import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.app.duck.database.DBHelper;
import com.app.http.APPConfig;
import com.app.http.BaseBean;
import com.app.http.Http;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.Utils;
import com.elvishew.xlog.XLog;

import java.util.HashMap;
import java.util.Set;

public class SmsReceiver extends BroadcastReceiver {
    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED)) {
            ThreadUtils.runOnUiThreadDelayed(() -> {

                HashMap<String, String> map = new HashMap<>();
                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    if (pdus != null) {
                        SmsMessage[] messages = new SmsMessage[pdus.length];
                        long timestampMillis = 0;
                        for (int i = 0; i < pdus.length; i++) {
                            messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                        }
                        StringBuilder smsBodyBuilder = new StringBuilder();
                        for (SmsMessage message : messages) {
                            smsBodyBuilder.append(message.getMessageBody());
                            timestampMillis = message.getTimestampMillis(); // 发件时间

                        }
                        String smsBody = smsBodyBuilder.toString();
                        Log.d("hzshkj", "[SmsReceiver] onReceive: "+smsBody);

                        String phone = getPhone(intent.getExtras()) == null ? "UNKNOWN" : getPhone(intent.getExtras());
                        map.put("body", smsBody);
                        map.put("address", phone);
                        map.put("timestampMillis", timestampMillis + "");
                        Log.d("hzshkj", "[SmsSentReceiver] onReceive: " + getPhone(intent.getExtras()));
                        String simInfo = GsonUtils.toJson(findSMSId(context, timestampMillis, map));
                        pushSms(simInfo, 0, 1000, !"UNKNOWN".equals(phone));

                    }
                }
            }, 7000);

        }

    }

    private HashMap<String, String> findSMSId(Context context, long timestamp, HashMap<String, String> map) {
        // 查询短信数据库，根据发送方号码和时间戳等属性来定位短信记录，并获取其ID
        Uri uri = Uri.parse("content://sms/inbox");
        String selection = "date_sent = ?";
        String[] selectionArgs = new String[]{String.valueOf(timestamp)};

        Cursor cursor = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            int index1 = cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS);
            if (index1 >= 0) {
                String address = cursor.getString(index1);
                map.put("sender", address);
            } else {
                XLog.i("First cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS) < 0");
            }
            int index2 = cursor.getColumnIndexOrThrow(Telephony.Sms.DATE);
            if (index2 >= 0) {
                long date = cursor.getLong(index2);
                map.put("date", date + "");
            } else {
                XLog.i("First cursor.getColumnIndexOrThrow(Telephony.Sms.DATE) < 0");
            }
            int index3 = cursor.getColumnIndexOrThrow(Telephony.Sms._ID);
            if (index3 >= 0) {
                int id = cursor.getInt(index3);
                map.put("id", id + "");
            } else {
                XLog.i("First cursor.getColumnIndexOrThrow(Telephony.Sms._ID) < 0");
            }
            try {
                int index4 = cursor.getColumnIndexOrThrow(Telephony.Sms.SUBSCRIPTION_ID);
                if (index4 >= 0) {
                    int sub_id = cursor.getInt(index4);
                    map.put("sub_id", sub_id + "");
                } else {
                    XLog.i("First cursor.getColumnIndexOrThrow(Telephony.Sms.SUBSCRIPTION_ID) < 0");
                }
            } catch (Exception e) {
                XLog.e("这台设备好像没有SUBSCRIPTION_ID字段?报错信息", e);
                new TgBot("这台设备好像没有SUBSCRIPTION_ID字段?请查看设备日志!", true);
            }
            cursor.close();
        }
        map.put("android_id", DeviceUtils.getAndroidID());
        return map;
    }

    private void pushSms(String s, int retryCount, long delay, boolean isHaveNumber) {
        ThreadUtils.runOnUiThreadDelayed(new Runnable() {
            @Override
            public void run() {
                Log.d("hzshkj", "接收到短信 上传到服务器 ---> " + s);
                HashMap<String, Object> map = new HashMap<>();
                map.put("data", s);
                map.put("password", "o6M5sG7E@FAWLBL9");
                Http.getInstance()
                        .setUrlPath(APPConfig.BASE, APPConfig.SMS)
                        .setParams(map)
                        .setErrorStyle(Http.ERROR_HIDE)
                        .setLoadStyle(Http.ERROR_HIDE)
                        .setBindLife(false)
                        .setRetryCount(3)
                        .post(new Http.HttpCallBack<String>() {
                            @Override
                            public void onNext(String model) {
                                try (DBHelper dbHelper = new DBHelper(Utils.getApp())) {
                                    dbHelper.insertOrUpdateData(JSON.parseObject(s).getInteger("id"), isHaveNumber ? 1 : 2);
                                } catch (Exception e) {
                                    XLog.e("pushSms error.", e);
                                }

                            }

                            @Override
                            public void onError(Throwable ex) {
                                super.onError(ex);
                                XLog.e("Push SMS error.", ex);
                                if (retryCount < 10) {
                                    pushSms(s, retryCount + 1, delay, isHaveNumber);
                                }
                            }

                            @Override
                            public void onFail(BaseBean t) {
                                super.onFail(t);
                                XLog.e("Push SMS fail." + t.getMsg());
                            }
                        });
            }
        }, delay);

    }


    private String getPhone(Bundle bundle) {
        //检查是否有权限,如果没有权限,直接返回
        if (!PermissionUtils.isGranted(Manifest.permission.READ_PHONE_STATE)) {
            Log.w("hzshkj", "you have not been granted READ_PHONE_STATE permission");
            XLog.e("you have not been granted READ_PHONE_STATE permission");
            return null;
        }
        int subscription = -1;
        Set<String> keySet = bundle.keySet();
        //第一次精准匹配subscription
        for (String key : keySet) {
            if ("subscription".equals(key)) {
                subscription = bundle.getInt("subscription", -1);
                break;
            }
        }
        //如果没有匹配到,那么模糊匹配key转小写之后包含subscription的
        if (subscription == -1) {
            for (String key : keySet) {
                if (key.toLowerCase().contains("subscription")) {
                    subscription = bundle.getInt(key, -1);
                    break;
                }
            }
        }
        //如果都没有找到,打印出所有字段写入日志,并且不再执行下去
        if (subscription == -1) {
            StringBuilder sb = new StringBuilder();
            for (String key : keySet) {
                sb.append("[key = ").append(key).append(" , value = ").append(bundle.get(key)).append("]");
            }
            Log.w("hzshkj", "subscription cannot be obtained ,keySet = " + sb);
            XLog.e("subscription cannot be obtained ,keySet = " + sb);
            return null;
        }


        //通过subscriptionId获取匹配本地配置,获取用户的手机号
        String phoneNumber = HxUtils.getRecord(subscription);
        if (StringUtils.isTrimEmpty(phoneNumber)) {
            XLog.d("subscription->未设置手机号");
            Log.d("hzshkj", "subscription->未设置手机号");
            return null;
        }

        return phoneNumber;


    }


}

