package com.cooleshow.metronome;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
import com.bigkoo.pickerview.view.OptionsPickerView;
import com.cooleshow.base.ui.activity.BaseActivity;
import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
import com.cooleshow.metronome.Utils.VolumeManager;
import com.cooleshow.metronome.adapter.MetronomeAdapter;
import com.cooleshow.metronome.constants.MetronomeConfig;
import com.cooleshow.metronome.constants.MetronomeType;
import com.cooleshow.metronome.databinding.ActivityMetronomeLayoutBinding;
import com.cooleshow.metronome.widget.CircularSeekBar;

import java.util.ArrayList;
import java.util.List;

import androidx.recyclerview.widget.LinearLayoutManager;

public class MetronomeActivity extends BaseActivity<ActivityMetronomeLayoutBinding> implements View.OnClickListener, VolumeManager.VolumeChangeListener {
    public MetronomeType currentBeatType;
    public int currentBeatRate = MetronomeConfig.DEFAULT_PLAY_RATE;
    public float currentNoteRate = MetronomeConfig.DEFAULT_NOTE_RATE;
    private SoundPool soundPool;
    private int tickVoiceId;
    private int tockVoiceId;
    private OptionsPickerView pvOptions;
    private int playPosition = 0;
    private boolean isPlaying = false;
    private Handler mHandler = new Handler();
    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            long delayMillis = (long) (1 / (currentBeatRate / 60d) * 1000 * currentNoteRate);
            boolean tickOrTock = isTickOrTock();
            if (tickOrTock) {
                soundPool.play(tickVoiceId, 1F, 1F, 0, 0, 1F);
            } else {
                soundPool.play(tockVoiceId, 1F, 1F, 0, 0, 1F);
            }
            if (mMetronomeAdapter != null) {
                mMetronomeAdapter.notifyData(playPosition);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //实现闪烁动画效果
                        mMetronomeAdapter.notifyData(MetronomeAdapter.DEFAULT_SELECT_POSITION);
                    }
                }, delayMillis / 2);
            }
            playPosition++;
            mHandler.postDelayed(mRunnable, delayMillis);
        }
    };
    private List<MetronomeType> beatSymbolLists;
    private int currentSelectPosition;
    private MetronomeAdapter mMetronomeAdapter;
    private VolumeManager mVolumeManager;

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        QMUIStatusBarHelper.setStatusBarLightMode(this);
    }

    @Override
    protected void initView() {
        initMidTitleToolBar(viewBinding.toolbarInclude.toolbar, "节拍器");
        viewBinding.toolbarInclude.toolbar.setBackgroundColor(Color.TRANSPARENT);
        updateSpeedText();
    }


    private void updateSpeedText() {
        viewBinding.tvSpeed.setText(String.valueOf(currentBeatRate));
    }

    @Override
    protected ActivityMetronomeLayoutBinding getLayoutView() {
        return ActivityMetronomeLayoutBinding.inflate(getLayoutInflater());
    }

    private void setBeat(MetronomeType metronomeType) {
        currentBeatType = metronomeType;
        viewBinding.tvCurrentBeat.setText(metronomeType.getName());
        playPosition = 0;
        mMetronomeAdapter.notifyData(MetronomeAdapter.DEFAULT_SELECT_POSITION);
        mMetronomeAdapter.setCount(getBeatSymbolCount());
        currentNoteRate = MetronomeType.getNoteSpeedValue(metronomeType);
        int noteDrawable = MetronomeConfig.getNoteDrawable(metronomeType);
        viewBinding.ivNote.setImageResource(noteDrawable);
    }

    private int getBeatSymbolCount() {
        int value = currentBeatType.getValue();
        if (value == MetronomeType.METRONOME_12_TYPE.getValue()
                || value == MetronomeType.METRONOME_14_TYPE.getValue()) {
            return 1;
        }

        if (value == MetronomeType.METRONOME_22_TYPE.getValue()
                || value == MetronomeType.METRONOME_24_TYPE.getValue()) {
            return 2;
        }

        if (value == MetronomeType.METRONOME_34_TYPE.getValue()
                || value == MetronomeType.METRONOME_38_TYPE.getValue()) {
            return 3;
        }

        if (value == MetronomeType.METRONOME_44_TYPE.getValue()) {
            return 4;
        }

        if (value == MetronomeType.METRONOME_68_TYPE.getValue()) {
            return 6;
        }

        if (value == MetronomeType.METRONOME_816_TYPE.getValue()) {
            return 8;
        }
        return 0;
    }

    @Override
    protected void initData() {
        super.initData();
        mMetronomeAdapter = new MetronomeAdapter();
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        viewBinding.recyclerView.setLayoutManager(linearLayoutManager);
        viewBinding.recyclerView.setAdapter(mMetronomeAdapter);
        //set default
        setBeat(MetronomeType.METRONOME_44_TYPE);
        initListener();
        mteronomeSoundPool();
        beatSymbolLists = new ArrayList<>();
        beatSymbolLists.add(MetronomeType.METRONOME_12_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_14_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_22_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_24_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_34_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_38_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_44_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_68_TYPE);
        beatSymbolLists.add(MetronomeType.METRONOME_816_TYPE);
        mVolumeManager = new VolumeManager(this);
        mVolumeManager.setVolumeChangeListener(this);
        mVolumeManager.registerReceiver();
        int streamVolume = mVolumeManager.getCurrentMusicVolume();
        int maxStreamVolume = mVolumeManager.getMaxMusicVolume();
        viewBinding.volumeSeekBar.setMax(maxStreamVolume);
        viewBinding.volumeSeekBar.setProgress(streamVolume);
        viewBinding.volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mVolumeManager.setCurrentMusicVolume(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    private void play() {
        mHandler.removeCallbacksAndMessages(null);
        soundPool.stop(tickVoiceId);
        soundPool.stop(tockVoiceId);
        mHandler.post(mRunnable);
        isPlaying = true;
        viewBinding.tvPlay.setText(getString(R.string.pause_play_str));
    }

    private void pausePlay() {
        mHandler.removeCallbacksAndMessages(null);
        soundPool.stop(tickVoiceId);
        soundPool.stop(tockVoiceId);
        isPlaying = false;
        viewBinding.tvPlay.setText(getString(R.string.play_str));
    }

    private void mteronomeSoundPool() {

        SoundPool.Builder builder = new SoundPool.Builder();
        //传入最多播放音频数量,
        builder.setMaxStreams(2);
        //AudioAttributes是一个封装音频各种属性的方法
        AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
        //设置音频流的合适的属性
        attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
        //加载一个AudioAttributes
        builder.setAudioAttributes(attrBuilder.build());

        soundPool = builder.build();

        tickVoiceId = soundPool.load(this, com.daya.live_teaching.R.raw.tick, 0);
        tockVoiceId = soundPool.load(this, com.daya.live_teaching.R.raw.tock, 0);
    }

    private int lastProgress = 0;

    private void initListener() {
        viewBinding.ivBeatValue.setOnClickListener(this);
        viewBinding.ivAdd.setOnClickListener(this);
        viewBinding.ivReduce.setOnClickListener(this);
        viewBinding.tvPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlaying) {
                    pausePlay();
                } else {
                    play();
                }
            }
        });
        viewBinding.cirSeekbar.setSeekBarChangeListener(new CircularSeekBar.OnSeekChangeListener() {
            @Override
            public void onProgressChange(CircularSeekBar view, int newProgress) {
                Log.i("newProgress", "newProgress:" + newProgress);
                Log.i("newProgress", "lastProgress:" + lastProgress);
                int difference = newProgress - lastProgress;
                if (Math.abs(difference) > 10) {
                    lastProgress = newProgress;
                    return;
                }
                lastProgress = newProgress;
                int result = difference / MetronomeConfig.PLAY_RATE_UNIT;
                if (difference <= -1) {
                    result = -1;
                }
                if (difference >= 1) {
                    result = 1;
                }
                if (result == 0) {
                    return;
                }
                Log.i("newProgress", "result:" + result);
                if (isCanChange(result)) {
                    currentBeatRate += result;
                } else {
                    return;
                }
                if (currentBeatRate < MetronomeConfig.MIN_PLAY_RATE) {
                    currentBeatRate = MetronomeConfig.MIN_PLAY_RATE;
                }
                if (currentBeatRate > MetronomeConfig.MAX_PLAY_RATE) {
                    currentBeatRate = MetronomeConfig.MAX_PLAY_RATE;
                }
                updateSpeedText();
            }
        });
    }

    public boolean isCanChange(int result) {
        if (result < 0) {
            return currentBeatRate != MetronomeConfig.MIN_PLAY_RATE;
        } else {
            return currentBeatRate != MetronomeConfig.MAX_PLAY_RATE;
        }
    }

    private boolean isTickOrTock() {
        if (currentBeatType.getValue() == MetronomeType.METRONOME_12_TYPE.getValue() && playPosition % 1 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_22_TYPE.getValue() && playPosition % 2 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_14_TYPE.getValue() && playPosition % 1 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_24_TYPE.getValue() && playPosition % 2 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_34_TYPE.getValue() && playPosition % 3 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_44_TYPE.getValue() && playPosition % 4 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_38_TYPE.getValue() && playPosition % 3 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_68_TYPE.getValue() && playPosition % 6 == 0) {
            return true;
        } else if (currentBeatType.getValue() == MetronomeType.METRONOME_816_TYPE.getValue() && playPosition % 8 == 0) {
            return true;
        } else {
            return false;
        }
    }

    private void selectSymbols() {
        pvOptions = new OptionsPickerBuilder(this, (options1, options2, options3, v) -> {
            this.currentSelectPosition = options1;
            MetronomeType metronomeType = beatSymbolLists.get(currentSelectPosition);
            viewBinding.tvCurrentBeat.setText(metronomeType.getName());
            setBeat(metronomeType);
            pausePlay();
        }).setTitleText("拍号").setTitleColor(Color.BLACK).setLayoutRes(R.layout.pickerview_beat_symbol_layout, v -> {
            //自定义布局中的控件初始化及事件处理
            final TextView tvSubmit = (TextView) v.findViewById(com.cooleshow.base.R.id.tv_finish);
            TextView ivCancel = (TextView) v.findViewById(com.cooleshow.base.R.id.tv_cancel);
            tvSubmit.setOnClickListener(v12 -> {
                pvOptions.returnData();
                pvOptions.dismiss();
            });
            ivCancel.setOnClickListener(v1 -> pvOptions.dismiss());

        }).isDialog(false).build();
        pvOptions.setPicker(beatSymbolLists);
        if (currentSelectPosition < beatSymbolLists.size()) {
            pvOptions.setSelectOptions(currentSelectPosition);
        }
        pvOptions.show();

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        try {
            mVolumeManager.unregisterReceiver();
            soundPool.release();
            soundPool = null;
            mHandler.removeCallbacksAndMessages(null);
        } catch (Exception e) {

        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.iv_beat_value) {
            selectSymbols();
            return;
        }

        if (id == R.id.iv_reduce) {
            //减速
            if (currentBeatRate != MetronomeConfig.MIN_PLAY_RATE) {
                updateAnim(-1);
            }
            return;
        }

        if (id == R.id.iv_add) {
            //加速
            if (currentBeatRate != MetronomeConfig.MAX_PLAY_RATE) {
                updateAnim(1);
            }
            return;
        }
    }

    private void updateAnim(int value) {
        int progress = viewBinding.cirSeekbar.getProgress();
        Log.i("qwer", "当前progress:" + progress);
        progress += value;
        if (progress >= MetronomeConfig.MAX_RATE_PROGRESS) {
            progress = 0;
        }
        if (progress < 0) {
            progress = MetronomeConfig.MAX_RATE_PROGRESS + value;
        }
        viewBinding.cirSeekbar.setProgress(progress);
    }

    @Override
    public void onVolumeChanged(int volume) {
        if (!checkActivityExist()) {
            return;
        }
        viewBinding.volumeSeekBar.setProgress(volume);
    }

}