package com.ads.cal.calculator.activity;

import android.Manifest;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.ads.cal.calculator.R;
import com.ads.cal.calculator.base.BaseActivity;
import com.ads.cal.calculator.utils.EventIdUtils;
import com.ads.cal.calculator.utils.LogUtils;

public class DecibelActivity extends BaseActivity {

    private static final int AUDIO_SAMPLE_RATE = 44100;
    private static final int AUDIO_CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
    private static final int AUDIO_ENCODING_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    private static final int PERMISSION_REQUEST_CODE = 1;
    private static final int MSG_UPDATE_DECIBEL = 1;

    private AudioRecord audioRecord;
    private boolean isRecording = false;
    private Handler handler;
    private LinearLayout pointer;
    private TextView decibelMinValue, decibelMaxValue, value;
    private LinearLayout layout;

    @Override
    protected String getPageExpEventId() {
        return EventIdUtils.DECIBEL_EXP;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.app_activity_decibel;
    }

    @Override
    protected void initView() {
        pointer = findViewById(R.id.pointer);
        value = findViewById(R.id.value);
        decibelMinValue = findViewById(R.id.min_value);
        decibelMaxValue = findViewById(R.id.max_value);
        layout = findViewById(R.id.standardsLayout);
        handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                if (msg.what == MSG_UPDATE_DECIBEL) {
                    double soundIntensity = (double) msg.obj;
                    updateDecibelUI(soundIntensity);
                }
            }
        };
        LinearLayout back = findViewById(R.id.back);
        back.setOnClickListener(v -> {
            if (layout.getVisibility() != View.GONE) {
                layout.setVisibility(View.GONE);
            }
        });

        findViewById(R.id.look).setOnClickListener(v -> {
         if (layout.getVisibility() != View.VISIBLE) {
             layout.setVisibility(View.VISIBLE);
         }
        });
    }

    private int minDecibel = 120, maxDecibel;
    private boolean firstUpdateValue = true;

    private void updateDecibelUI(double decibel) {
        float rotation = (float) ((decibel + 120) / (300 + 120) * 300.0 - 60.0);
        LogUtils.log("rotation", "rotation   "+ rotation);
        // 创建一个属性动画以平滑旋转视图
        ObjectAnimator animator = ObjectAnimator.ofFloat(pointer, "rotation", rotation);
        animator.setDuration(300); // 设置动画持续时间（毫秒）
        animator.start();
        decibel = 90 - Math.abs(decibel);

        if (decibel > maxDecibel) {
            maxDecibel = (int) decibel;
        }
        decibelMaxValue.setText(String.format("%s dB",  maxDecibel));
        value.setText(String.valueOf((int) decibel));

        if (firstUpdateValue) {
            firstUpdateValue = false;
            return;
        }
        if (decibel < minDecibel) {
            minDecibel = (int) decibel;
        }
        decibelMinValue.setText(String.format("%s dB",  minDecibel));

    }

    @Override
    protected void initData() {
        startRecording();
    }

    private void startRecording() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSION_REQUEST_CODE);
            LogUtils.log("no Permission   ");
            return;
        }

        int bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_ENCODING_FORMAT);
        if (bufferSize == AudioRecord.ERROR_BAD_VALUE) {
            LogUtils.log("处理错误：无效的参数   ");
            // 处理错误：无效的参数
            return;
        }

        audioRecord = new AudioRecord.Builder()
                .setAudioSource(MediaRecorder.AudioSource.MIC)
                .setAudioFormat(new AudioFormat.Builder()
                        .setEncoding(AUDIO_ENCODING_FORMAT)
                        .setSampleRate(AUDIO_SAMPLE_RATE)
                        .setChannelMask(AUDIO_CHANNEL_CONFIG)
                        .build())
                .setBufferSizeInBytes(bufferSize)
                .build();

        audioRecord.startRecording();
        isRecording = true;

        new Thread(() -> {
            short[] buffer = new short[bufferSize];
            int sampleCount = 0;
            double soundIntensitySum = 0;

            while (isRecording) {
                audioRecord.read(buffer, 0, bufferSize);

                double maxAmplitude = 0;
                for (short s : buffer) {
                    double amplitude = Math.abs((double) s / Short.MAX_VALUE);
                    maxAmplitude = Math.max(maxAmplitude, amplitude);
                }

                soundIntensitySum += maxAmplitude * maxAmplitude;
                sampleCount++;
                LogUtils.log("sampleCount=  "+sampleCount +" bufferSize=  "+bufferSize+"   "+AUDIO_SAMPLE_RATE / (bufferSize * 3));
                // 每秒更新一次分贝值
                if (sampleCount == AUDIO_SAMPLE_RATE / (bufferSize * 3)) {
                    // 计算平均声音强度的平方
                    double averageSoundIntensitySquared = soundIntensitySum / sampleCount;
                    LogUtils.log("averageSoundIntensitySquared=  "+averageSoundIntensitySquared);
                    // 计算分贝值
                    double decibel = 10 * Math.log10(averageSoundIntensitySquared);
                    LogUtils.log("decibel=  "+decibel);
                    // 发送分贝值到主线程更新UI
                    Message message = handler.obtainMessage(MSG_UPDATE_DECIBEL, decibel);
                    handler.sendMessage(message);

                    // 重置计数器和声音强度总和
                    sampleCount = 0;
                    soundIntensitySum = 0;
                }
            }

            audioRecord.stop();
            audioRecord.release();
        }).start();
    }

    private void stopRecording() {
        isRecording = false;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startRecording();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopRecording();
    }

    @Override
    public void onBackPressed() {
        if (layout.getVisibility() != View.GONE) {
            layout.setVisibility(View.GONE);
            return;
        }
        super.onBackPressed();
    }

    public static void instance(Context context) {
        Intent intent = new Intent(context, DecibelActivity.class);
        context.startActivity(intent);
    }
}
