package com.ydl.component.music;

import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.ydl.component.R;
import com.ydl.media.audio.AudioPlayer;
import com.ydl.media.audio.OnPlayerEventListener;
import com.ydl.media.audio.enums.PlayModeEnum;
import com.ydl.media.audio.model.Music;
import com.ydl.media.audio.utils.CoverImageUtils;
import com.ydl.media.view.PlayTypeEnum;
import com.ydl.media.view.PlayerFloatHelper;
import com.ydl.ydlcommon.utils.LogUtil;
import com.yidianling.common.tools.ToastUtil;

import java.util.HashMap;
import java.util.Locale;
import java.util.Objects;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;


/**
 * Created by haorui on 2019-10-28 .
 * Des:
 */
public class PlayFragment extends Fragment implements View.OnClickListener,
        SeekBar.OnSeekBarChangeListener, OnPlayerEventListener {
    @BindView(R.id.ll_content)
    LinearLayout llContent;
    @BindView(R.id.iv_play_page_bg)
    ImageView ivPlayingBg;
    @BindView(R.id.iv_back)
    ImageView ivBack;
    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_artist)
    TextView tvArtist;
    @BindView(R.id.sb_progress)
    SeekBar sbProgress;
    @BindView(R.id.tv_current_time)
    TextView tvCurrentTime;
    @BindView(R.id.tv_total_time)
    TextView tvTotalTime;
    @BindView(R.id.iv_mode)
    ImageView ivMode;
    @BindView(R.id.iv_play)
    ImageView ivPlay;
    @BindView(R.id.iv_next)
    ImageView ivNext;
    @BindView(R.id.iv_prev)
    ImageView ivPrev;
    @BindView(R.id.iv_cover)
    ImageView ivCover;

    int mLastProgress;
    boolean isDraggingProgress;
    private Unbinder unbinder;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_play, container, false);
        unbinder = ButterKnife.bind(this, rootView);
        return rootView ;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initPlayMode();
        onChangeImpl(AudioPlayer.Companion.get().getPlayMusic());
        AudioPlayer.Companion.get().addOnPlayEventListener(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        setListener();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }

    protected void setListener() {
        ivBack.setOnClickListener(this);
        ivMode.setOnClickListener(this);
        ivPlay.setOnClickListener(this);
        ivPrev.setOnClickListener(this);
        ivNext.setOnClickListener(this);
        sbProgress.setOnSeekBarChangeListener(this);
    }

    void initPlayMode() {
        int mode = AudioPlayer.Companion.get().getPlayMode().value();
        ivMode.setImageLevel(mode);
        AudioPlayer.Companion.get().play();
        showFloatView();
    }

    @Override
    public void onChange(Music music) {
        onChangeImpl(music);
    }

    @Override
    public void onPlayerStart() {
        ivPlay.setSelected(true);
    }

    @Override
    public void onPlayerPause() {
        ivPlay.setSelected(false);
    }

    /**
     * 更新播放进度
     */
    @Override
    public void onPublish(int percent,long currentPosition) {
        if (!isDraggingProgress) {
            sbProgress.setProgress((int) currentPosition);
        }
    }

    @Override
    public void onBufferingUpdate(int percent) {
        if(percent==0) {
            return;
        }
        sbProgress.setSecondaryProgress(sbProgress.getMax() * 100 / percent);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_back:
                onBackPressed();
                break;
            case R.id.iv_mode:
                switchPlayMode();
                break;
            case R.id.iv_play:
                play();
                showFloatView();
                break;
            case R.id.iv_next:
                next();
                break;
            case R.id.iv_prev:
                prev();
                break;
        }
    }

    private void showFloatView() {
        if(!PlayerFloatHelper.Companion.isShow(getActivity())) {
            PlayerFloatHelper.Companion.show(getActivity(), PlayTypeEnum.PLAY_TYPE_FM,new HashMap<>());
        }else {
            PlayerFloatHelper.Companion.showIfPlaying(getActivity());
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (seekBar == sbProgress) {
            if (Math.abs(progress - mLastProgress) >= DateUtils.SECOND_IN_MILLIS) {
                tvCurrentTime.setText(formatTime(progress));
                mLastProgress = progress;
            }
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if (seekBar == sbProgress) {
            isDraggingProgress = true;
        }
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (seekBar == sbProgress) {
            isDraggingProgress = false;
            if (AudioPlayer.Companion.get().isPlaying() || AudioPlayer.Companion.get().isPausing()) {
                int progress = seekBar.getProgress();
                AudioPlayer.Companion.get().seekTo(-1, progress);
            } else {
                seekBar.setProgress(0);
            }
        }
    }

    void onChangeImpl(Music music) {
        if (music == null) {
            return;
        }

        tvTitle.setText(music.getTitle());
        tvArtist.setText(music.getArtist());
        sbProgress.setProgress((int) AudioPlayer.Companion.get().getAudioPosition());
        sbProgress.setSecondaryProgress(0);
        sbProgress.setMax((int) AudioPlayer.Companion.get().getDuration());

        mLastProgress = 0;
        tvCurrentTime.setText(R.string.play_time_start);
        tvTotalTime.setText(formatTime(AudioPlayer.Companion.get().getDuration()));

        setCoverAndBg(music);
        if (AudioPlayer.Companion.get().isPlaying() || AudioPlayer.Companion.get().isPreparing()) {
            ivPlay.setSelected(true);
        } else {
            ivPlay.setSelected(false);
        }
    }

    void play() {
        AudioPlayer.Companion.get().playPause();
    }

    void next() {
        AudioPlayer.Companion.get().next();
    }

    void prev() {
        AudioPlayer.Companion.get().prev();
    }

    void switchPlayMode() {
        PlayModeEnum mode = AudioPlayer.Companion.get().getPlayMode();
        switch (mode) {
            case LIST_LOOP:
                mode = PlayModeEnum.SHUFFLE;
                ToastUtil.toastShort(getString(R.string.mode_shuffle));
                break;
            case SHUFFLE:
                mode = PlayModeEnum.SINGLE;
                ToastUtil.toastShort(getString(R.string.mode_one));
                break;
            case SINGLE_LOOP:
                mode = PlayModeEnum.LIST_LOOP;
                ToastUtil.toastShort(getString(R.string.mode_loop));
                break;
        }
        AudioPlayer.Companion.get().setPlayMode(mode);
        initPlayMode();
    }

    void onBackPressed() {
        getActivity().onBackPressed();
        ivBack.setEnabled(false);
    }

    void setCoverAndBg(Music music) {
        CoverImageUtils.INSTANCE.loadRound(Objects.requireNonNull(music.getCoverPath()), bitmap -> ivCover.setImageBitmap(bitmap));
        CoverImageUtils.INSTANCE.loadBlur(music.getCoverPath(), bitmap -> ivPlayingBg.setImageBitmap(bitmap));
    }

    String formatTime(long time) {
        return formatTime("mm:ss", time);
    }

    public static String formatTime(String pattern, long milli) {
        int m = (int) (milli / DateUtils.MINUTE_IN_MILLIS);
        int s = (int) ((milli / DateUtils.SECOND_IN_MILLIS) % 60);
        String mm = String.format(Locale.getDefault(), "%02d", m);
        String ss = String.format(Locale.getDefault(), "%02d", s);
        return pattern.replace("mm", mm).replace("ss", ss);
    }

    @Override
    public void onDestroy() {
        AudioPlayer.Companion.get().removeOnPlayEventListener(this);
        PlayerFloatHelper.Companion.onDestroy();
        super.onDestroy();
    }

    @Override
    public void onPrepared(long duration) {
        sbProgress.setMax((int) duration);
        tvTotalTime.setText(formatTime(duration));
    }

    @Override
    public void onComplete() {
        LogUtil.e("onComplete");
    }
}