package cc.winboll.studio.contacts.phonecallui;

import android.content.ContentResolver;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.provider.CallLog;
import android.telecom.Call;
import android.telecom.InCallService;
import android.telephony.TelephonyManager;

import cc.winboll.studio.contacts.ActivityStack;
import cc.winboll.studio.contacts.model.RingTongBean;
import cc.winboll.studio.contacts.dun.Rules;
import cc.winboll.studio.contacts.fragments.CallLogFragment;
import cc.winboll.studio.libappbase.LogUtils;

import java.io.File;
import java.io.IOException;

/**
 * @Author aJIEw, ZhanGSKen&豆包大模型<zhangsken@qq.com>
 * @Date 2025/02/13 06:58:04
 * @Describe 通话状态监听服务（需 Android 6.0+），负责通话状态回调、录音、铃音控制及黑白名单校验
 * @see PhoneCallActivity
 * @see android.telecom.InCallService
 */
public class PhoneCallService extends InCallService {
    // ====================== 常量定义区 ======================
    public static final String TAG = "PhoneCallService";
    // 强制指定正确常量值，彻底解决冲突
    // TelephonyManager 通话状态
    //private static final int CALL_STATE_OFFHOOK = TelephonyManager.CALL_STATE_OFFHOOK; // 固定值=2
    //private static final int CALL_STATE_IDLE = TelephonyManager.CALL_STATE_IDLE;       // 固定值=0
    //private static final int CALL_STATE_RINGING_TELE = TelephonyManager.CALL_STATE_RINGING; // 固定值=1
    // Call 通话状态
	private static final int CALL_STATE_IDLE = Call.STATE_NEW;
    private static final int CALL_STATE_RINGING = Call.STATE_RINGING; //正确值=1
    private static final int CALL_STATE_CONNECTING = Call.STATE_CONNECTING; //正确值=3
    private static final int CALL_STATE_ACTIVE = Call.STATE_ACTIVE; //正确值=2
    private static final int CALL_STATE_DISCONNECTED = Call.STATE_DISCONNECTED; //正确值=4

    // ====================== 成员变量区 ======================
    private MediaRecorder mMediaRecorder;
    private Call.Callback mCallCallback;

    // ====================== 内部枚举类 ======================
    public enum CallType {
        CALL_IN,
        CALL_OUT
		}

    // ====================== 生命周期方法区 ======================
    @Override
    public void onCreate() {
        super.onCreate();
        initCallCallback();
        LogUtils.d(TAG, "onCreate: 通话监听服务已创建");
    }

    @Override
    public void onCallAdded(Call call) {
        super.onCallAdded(call);
        if (call == null) {
            LogUtils.w(TAG, "onCallAdded: 新增通话为null，跳过处理");
            return;
        }

        call.registerCallback(mCallCallback);
        PhoneCallManager.sCurrentCall = call;
        LogUtils.d(TAG, "onCallAdded: 新增通话已注册回调 | 状态码=" + call.getState() + " | 描述=" + getCallStateDesc(call.getState()));

        CallType callType = judgeCallType(call.getState());
        if (callType == null) {
            LogUtils.w(TAG, "onCallAdded: 无法识别通话类型 | 状态码=" + call.getState());
            return;
        }

        String phoneNumber = getPhoneNumberFromCall(call);
        if (phoneNumber == null || phoneNumber.isEmpty()) {
            LogUtils.w(TAG, "onCallAdded: 通话号码为空");
            return;
        }
        LogUtils.d(TAG, "onCallAdded: 通话类型=" + callType.name() + " | 号码=" + phoneNumber);

        handleRingerAndRuleCheck(phoneNumber, callType, call);
    }

    @Override
    public void onCallRemoved(Call call) {
        super.onCallRemoved(call);
        if (call != null) {
            call.unregisterCallback(mCallCallback);
            LogUtils.d(TAG, "onCallRemoved: 通话回调已注销");
        }
        PhoneCallManager.sCurrentCall = null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releaseRecorder();
        CallLogFragment.updateCallLogFragment();
        LogUtils.d(TAG, "onDestroy: 通话服务已销毁，资源已释放");
    }

    // ====================== 核心修复：通话状态回调 ======================
    private void initCallCallback() {
        mCallCallback = new Call.Callback() {
            @Override
            public void onStateChanged(Call call, int state) {
                super.onStateChanged(call, state);
                LogUtils.d(TAG, "onStateChanged: 状态变更 | 状态码=" + state + " | 描述=" + getCallStateDesc(state));

                switch (state) {
						// 仅合并值为2的两个状态，其他状态独立分支
                    case CALL_STATE_ACTIVE:
                    //case CALL_STATE_OFFHOOK:
                        long callId = getCurrentCallId();
                        if (callId != -1) {
                            LogUtils.d(TAG, "onStateChanged: 通话接通/活跃，启动录音 | 通话ID=" + callId);
                            startRecording(callId);
                        } else {
                            LogUtils.w(TAG, "onStateChanged: 未获取到通话ID，无法录音");
                        }
                        break;
						// 状态码1独立分支，彻底解决重复问题
                    case CALL_STATE_RINGING:
                        LogUtils.d(TAG, "onStateChanged: 通话处于响铃状态");
                        break;
                    case CALL_STATE_IDLE:
                        LogUtils.d(TAG, "onStateChanged: 通话挂断，停止录音");
                        stopRecording();
                        break;
                    case CALL_STATE_DISCONNECTED:
                        ActivityStack.getInstance().finishActivity(PhoneCallActivity.class);
                        LogUtils.d(TAG, "onStateChanged: 通话断开，关闭通话界面");
                        break;
                    case CALL_STATE_CONNECTING:
                        LogUtils.d(TAG, "onStateChanged: 通话正在连接");
                        break;
                    default:
                        LogUtils.w(TAG, "onStateChanged: 未处理的状态码=" + state);
                        break;
                }
            }
        };
    }

    // ====================== 核心业务方法区 ======================
    private CallType judgeCallType(int callState) {
        switch (callState) {
            case CALL_STATE_RINGING:
                return CallType.CALL_IN;
            case CALL_STATE_CONNECTING:
                return CallType.CALL_OUT;
            default:
                return null;
        }
    }

    private String getPhoneNumberFromCall(Call call) {
        try {
            Call.Details details = call.getDetails();
            if (details == null || details.getHandle() == null) {
                return null;
            }
            return details.getHandle().getSchemeSpecificPart();
        } catch (Exception e) {
            LogUtils.e(TAG, "getPhoneNumberFromCall: 解析号码失败", e);
            return null;
        }
    }

    private void handleRingerAndRuleCheck(String phoneNumber, CallType callType, Call call) {
        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioManager == null) {
            LogUtils.e(TAG, "handleRingerAndRuleCheck: 音频管理器获取失败");
            startPhoneCallActivity(phoneNumber, callType);
            return;
        }

        RingTongBean ringTongBean = RingTongBean.loadBean(this, RingTongBean.class);
        if (ringTongBean == null) {
            ringTongBean = new RingTongBean();
            RingTongBean.saveBean(this, ringTongBean);
            LogUtils.d(TAG, "handleRingerAndRuleCheck: 铃音配置已初始化");
        }

        restoreRingerVolume(audioManager, ringTongBean);

        if (!Rules.getInstance(this).isAllowed(phoneNumber)) {
            handleForbiddenCall(audioManager, ringTongBean, call);
            return;
        }

        startPhoneCallActivity(phoneNumber, callType);
    }

    private void restoreRingerVolume(AudioManager audioManager, RingTongBean bean) {
        try {
            int currentVol = audioManager.getStreamVolume(AudioManager.STREAM_RING);
            int configVol = bean.getStreamVolume();
            if (currentVol != configVol) {
                audioManager.setStreamVolume(AudioManager.STREAM_RING, configVol, 0);
                LogUtils.d(TAG, "restoreRingerVolume: 音量恢复 | 配置值=" + configVol + " | 当前值=" + currentVol);
            }
        } catch (SecurityException e) {
            LogUtils.e(TAG, "restoreRingerVolume: 音量设置失败（权限不足）", e);
        }
    }

    private void handleForbiddenCall(AudioManager audioManager, RingTongBean bean, Call call) {
        try {
            audioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
            call.disconnect();
            Thread.sleep(500);
            audioManager.setStreamVolume(AudioManager.STREAM_RING, bean.getStreamVolume(), 0);
            LogUtils.d(TAG, "handleForbiddenCall: 禁止通话处理完成");
        } catch (SecurityException e) {
            LogUtils.e(TAG, "handleForbiddenCall: 音量操作失败", e);
        } catch (InterruptedException e) {
            LogUtils.e(TAG, "handleForbiddenCall: 延迟线程中断", e);
            Thread.currentThread().interrupt();
        }
    }

    private void startPhoneCallActivity(String phoneNumber, CallType callType) {
        PhoneCallActivity.actionStart(this, phoneNumber, callType);
        LogUtils.d(TAG, "startPhoneCallActivity: 通话界面已启动");
    }

    // ====================== 录音相关方法区 ======================
    private void startRecording(long callId) {
        releaseRecorder();
        mMediaRecorder = new MediaRecorder();
        try {
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            String path = getOutputFilePath(callId);
            mMediaRecorder.setOutputFile(path);
            mMediaRecorder.prepare();
            mMediaRecorder.start();
            LogUtils.d(TAG, "startRecording: 录音启动成功 | 路径=" + path);
        } catch (IOException | IllegalStateException e) {
            LogUtils.e(TAG, "startRecording: 录音启动失败", e);
            releaseRecorder();
        }
    }

    private void stopRecording() {
        if (mMediaRecorder != null) {
            try {
                mMediaRecorder.stop();
            } catch (IllegalStateException e) {
                LogUtils.e(TAG, "stopRecording: 录音停止失败", e);
            } finally {
                releaseRecorder();
            }
        }
    }

    private String getOutputFilePath(long callId) {
        File dir = getExternalFilesDir(TAG);
        if (dir == null) {
            dir = new File(getFilesDir(), TAG);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }
        return new File(dir, String.format("call_%d.mp4", callId)).getAbsolutePath();
    }

    private void releaseRecorder() {
        if (mMediaRecorder != null) {
            mMediaRecorder.release();
            mMediaRecorder = null;
            LogUtils.d(TAG, "releaseRecorder: 录音资源已释放");
        }
    }

    // ====================== 辅助工具方法区 ======================
    private long getCurrentCallId() {
        ContentResolver resolver = getApplicationContext().getContentResolver();
        if (resolver == null) {
            LogUtils.w(TAG, "getCurrentCallId: 内容解析器为null");
            return -1;
        }

        Uri uri = CallLog.Calls.CONTENT_URI;
        String[] projection = {CallLog.Calls._ID};
        String selection = CallLog.Calls.TYPE + " = " + CallLog.Calls.OUTGOING_TYPE
			+ " OR " + CallLog.Calls.TYPE + " = " + CallLog.Calls.INCOMING_TYPE;
        String sort = CallLog.Calls.DATE + " DESC";
        Cursor cursor = null;

        try {
            cursor = resolver.query(uri, projection, selection, null, sort);
            if (cursor != null && cursor.moveToFirst()) {
                long id = cursor.getLong(cursor.getColumnIndex(CallLog.Calls._ID));
                LogUtils.d(TAG, "getCurrentCallId: 通话ID=" + id);
                return id;
            }
            LogUtils.w(TAG, "getCurrentCallId: 未查询到通话记录");
            return -1;
        } catch (SecurityException e) {
            LogUtils.e(TAG, "getCurrentCallId: 查询失败（权限不足）", e);
            return -1;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    private String getCallStateDesc(int state) {
        switch (state) {
            case CALL_STATE_RINGING:
                return "响铃";
            case CALL_STATE_CONNECTING:
                return "连接中";
            case CALL_STATE_ACTIVE:
                return "活跃";
            //case CALL_STATE_OFFHOOK:
            //    return "摘机";
            case CALL_STATE_IDLE:
                return "空闲";
            case CALL_STATE_DISCONNECTED:
                return "已断开";
            default:
                return "未知状态";
        }
    }
}

