package com.atmob.voiceai.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.atmob.voiceai.R;

public class AudioProgressBar extends View {


    private Paint progressPaint;
    private int progressColor = 0xFFFF5656;
    private int lastProgressColor = 0xFFFF5656;
    private RectF progressRect;
    private int max = 1;
    private int currentProgress = 0;
    private int width;
    private long changeColorTime = 1000;
    ValueAnimator animator;
    private int startColor;

    private OnProgressColorChangeListener onProgressColorChangeListener;


    public AudioProgressBar(Context context) {
        this(context, null);
    }

    public AudioProgressBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AudioProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AudioProgressBar, defStyleAttr, 0);
        startColor = typedArray.getColor(R.styleable.AudioProgressBar_startColor, 0xFFFF5656);
        typedArray.recycle();
        initProgress();
    }

    public void setOnProgressColorChangeListener(OnProgressColorChangeListener onProgressColorChangeListener) {
        this.onProgressColorChangeListener = onProgressColorChangeListener;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animator != null) {
            animator.cancel();
        }
    }

    private void initProgress() {
        progressPaint = new Paint();
        progressPaint.setColor(progressColor);
        progressRect = new RectF();
        animator = ValueAnimator.ofFloat(0f, 1f);
        animator.setDuration(changeColorTime);
    }

    public void setMax(int max) {
        this.max = max;
        int currentRectWidth = getCurrentRectWidth();
        progressRect.set(0, 0, currentRectWidth, getHeight());
        invalidate();
    }

    private int getCurrentRectWidth() {
        return width * currentProgress / max;
    }

    public void setProgress(int progress) {
        if (currentProgress > max) {
            currentProgress = max;
        } else {
            this.currentProgress = progress;
        }
        if (currentProgress == 0) {
            animator.cancel();
            progressColor = startColor;
            progressPaint.setColor(progressColor);
            if (onProgressColorChangeListener != null)
                onProgressColorChangeListener.onProgressColorChange(progressColor);
        }
        int currentRectWidth = getCurrentRectWidth();
        progressRect.set(0, 0, currentRectWidth, getHeight());
        invalidate();
    }


    public void setProgressColor(int color) {
        lastProgressColor = progressColor;
        progressColor = color;

        if (animator.isRunning()) {
            animator.cancel();
        }
        animator.addUpdateListener(animation -> {
            float fraction = (float) animation.getAnimatedValue();
            int evaluate = evaluate(fraction, lastProgressColor, progressColor);
            progressPaint.setColor(evaluate);
            if (onProgressColorChangeListener != null)
                onProgressColorChangeListener.onProgressColorChange(evaluate);
            invalidate();
        });
        animator.start();
        Log.d("AudioProgressBar", "start");
    }


    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(progressRect, progressPaint);
    }


    public int evaluate(float fraction, int startColor, int endColor) {
        float startA = ((startColor >> 24) & 0xff) / 255.0f;
        float startR = ((startColor >> 16) & 0xff) / 255.0f;
        float startG = ((startColor >> 8) & 0xff) / 255.0f;
        float startB = (startColor & 0xff) / 255.0f;

        float endA = ((endColor >> 24) & 0xff) / 255.0f;
        float endR = ((endColor >> 16) & 0xff) / 255.0f;
        float endG = ((endColor >> 8) & 0xff) / 255.0f;
        float endB = (endColor & 0xff) / 255.0f;

        // convert from sRGB to linear
        startR = (float) Math.pow(startR, 2.2);
        startG = (float) Math.pow(startG, 2.2);
        startB = (float) Math.pow(startB, 2.2);

        endR = (float) Math.pow(endR, 2.2);
        endG = (float) Math.pow(endG, 2.2);
        endB = (float) Math.pow(endB, 2.2);

        // compute the interpolated color in linear space
        float a = startA + fraction * (endA - startA);
        float r = startR + fraction * (endR - startR);
        float g = startG + fraction * (endG - startG);
        float b = startB + fraction * (endB - startB);

        // convert back to sRGB in the [0..255] range
        a = a * 255.0f;
        r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;
        g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;
        b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;

        return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);
    }

    public interface OnProgressColorChangeListener {
        void onProgressColorChange(int color);
    }
}
