package com.mytatvarnsdk.myView.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.mytatvarnsdk.R;
import com.mytatvarnsdk.activity.BtManageActivity;
import com.mytatvarnsdk.myView.popupwindow.BPopupWindow;
import com.mytatvarnsdk.myView.popupwindow.PopupType;
import com.mytatvarnsdk.myView.popupwindow.PopupWindowManagement;

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

import cgmblelib.base.BApplication;
import cgmblelib.custom.livedata.scan.PocDeviceAndRssi;
import cgmblelib.database.entity.PocDevice;
import cgmblelib.utils.SharedPreferencesLibraryUtil;
import cgmblelib.utils.Tool;
import ist.com.sdk.EDevice;


/***
 * 搜索到的发射器
 * @author minyuchun
 */
public class TransmitterState extends LinearLayout {
  /**
   * 发射器列表
   */
  public RecyclerView recyclerView;
  public ImageView transmitterImg;
  /**
   * 发射器搜索列表
   */
  private List<PocDeviceAndRssi> mPocDeviceList;
  private LinearLayout head;
  /**
   * 连接回调
   */
  private OnDeviceConnectionListener onDeviceConnectionListener;

  private BtManageActivity mActivity;

  SearchListAdapter adapter;

  public boolean isConnecting = false;
  // 下拉箭头的转180°动画
  private Animation reverseUpAnimation;
  private Animation reverseDownAnimation;
  private ImageView imgvArrow;
  private TextView txtvMsg;

  private RelativeLayout pullView;


  /**
   * 正在加载
   */
  public static final int LOADING = 0;
  /**
   * 加载成功
   */
  public static final int LOAD_SUCCESS = 1;//加载成功

  /**
   * 箭头向下
   */
  public static final int LOAD_OVER = 4;//正常状态
  /**
   * 箭头向上
   */
  public static final int LOAD_BEFOR = 5;//即将开始加载

  /**
   * 当前状态
   */
  private int currentState;

  public int mearchTop;
  public float min = 1;

  public boolean isNoTouch = true;

  private ValueAnimator upAnimator;

  public volatile int upstate = -1;

  private float mLastY;


  public TransmitterState(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initView(context);
  }

  public TransmitterState(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    initView(context);
  }

  public TransmitterState(Context context) {
    super(context);
    initView(context);
  }

  private void initView(Context context) {
    mPocDeviceList = new ArrayList<>();
    adapter = new SearchListAdapter(mPocDeviceList);
    reverseUpAnimation = AnimationUtils.loadAnimation(
      context, R.anim.reverse_up_anim);
    reverseDownAnimation = AnimationUtils.loadAnimation(
      context, R.anim.reverse_down_anim);
    // 添加匀速转动动画
    LinearInterpolator lir = new LinearInterpolator();
    reverseUpAnimation.setInterpolator(lir);

    View view = LayoutInflater.from(context).inflate(R.layout.activity_transmitter_state, this);

    pullView = view.findViewById(R.id.pull_rl);
    setViewHeight(pullView, 1);
    imgvArrow = view.findViewById(R.id.pull_icon);
    txtvMsg = view.findViewById(R.id.state_tv);


    mearchTop = getWidgetWidthAndHeight(pullView)[1];

    recyclerView = view.findViewById(R.id.search_list_recycler);
    head = view.findViewById(R.id.search_list_head);
    LinearLayoutManager layoutManager = new LinearLayoutManager(context);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);
    int space = 16;
    recyclerView.addItemDecoration(new SpacesItemDecoration(space));
    transmitterImg = view.findViewById(R.id.transmitter_img);
  }

  /**
   * 设置下拉刷新布局高度改变
   *
   * @param gap 增加的高度
   */
  public void setUpHeightVisible(float gap) {
    int height = (int) (pullView.getLayoutParams().height + gap);
    float minHeight;

    if (upstate == LOAD_OVER || upstate == LOAD_BEFOR || upstate == -1) {
      minHeight = min;
    } else {
      minHeight = mearchTop;
    }
    if (height > minHeight) {
      recyclerView.scrollToPosition(0);
    }
    height = (int) Math.max(height, minHeight);
    setViewHeight(pullView, height);

    //根据高度更新状态
    if (upstate == LOAD_OVER || upstate == LOAD_BEFOR || upstate == -1) {
      upRefreshState(height > mearchTop ? LOAD_BEFOR : LOAD_OVER);
    }
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    boolean dispatched = super.onInterceptTouchEvent(ev);
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mLastY = ev.getY();
        break;
      case MotionEvent.ACTION_MOVE:
        if (Math.abs(ev.getY() - mLastY) > 10) {
          dispatched = true;
          getParent().requestDisallowInterceptTouchEvent(true);
          break;
        }
        break;
      default:
        break;
    }

    return dispatched;
  }

  /**
   * 下拉刷新动画
   *
   * @param upState 当前状态
   */
  public void startUpAnimation(int upState) {
    float stand = upState == LOAD_BEFOR || upState == LOADING ? mearchTop : min;
    int height = pullView.getLayoutParams().height;
    if (height == stand) {
      return;
    }

    final int load = getNextState(upState);
    upAnimator = ValueAnimator.ofFloat(height, stand);
    upAnimator.setInterpolator(new DecelerateInterpolator(1));
    upAnimator.addUpdateListener(animation -> {
      float value = (float) animation.getAnimatedValue();
      setViewHeight(pullView, value);
    });
    upAnimator.addListener(new AnimatorListenerAdapter() {
      @Override
      public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        if (load != upstate) {
          upRefreshState(load);
        }
      }
    });

    if (upState == LOAD_SUCCESS) {
      upAnimator.setDuration(500);
      upAnimator.start();
    } else {
      upAnimator.setDuration(200);
      upAnimator.start();
    }
  }

  private int getNextState(int refreshState) {
    int load = refreshState;
    switch (refreshState) {
      case LOAD_BEFOR:
        if (isNoTouch) {
          load = LOADING;
        }
        break;
      case LOAD_SUCCESS:
        load = LOAD_OVER;
        break;
      case LOADING:
      case LOAD_OVER:
        break;
    }
    return load;
  }

  public void clearUpAnimation() {
    if (upAnimator != null && upAnimator.isRunning()) {
      upAnimator.removeAllUpdateListeners();
      upAnimator.pause();
      upAnimator.cancel();
    }
  }


  /**
   * 更改View的高度
   *
   * @param view  要更改的条目
   * @param value 高度值
   */
  public void setViewHeight(View view, float value) {
    ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
    layoutParams.height = (int) value;
    view.setLayoutParams(layoutParams);
  }

  public void upRefreshState(int refreshState) {
    if (this.upstate != refreshState) {
      synchronized (this) {
        if (this.upstate != refreshState) {
          int loadstate = -1;
          String msg = "";
          switch (refreshState) {
            case LOAD_OVER://4
              loadstate = LOAD_OVER;
              msg = mActivity.getString(R.string.loading_pull);
              break;
            case LOAD_BEFOR://5
              loadstate = LOAD_BEFOR;
              msg = mActivity.getString(R.string.loading_release);
              break;
            case LOADING://0
              loadstate = LOADING;
              msg = mActivity.getString(R.string.loading) + "...";
              if (transmitterImg.getVisibility() == GONE) {
                ((BtManageActivity) mActivity).checkBTGPS();
              }
              break;
            case LOAD_SUCCESS://1
              loadstate = LOAD_SUCCESS;
//                            msg = "Load successfully";
              break;
          }
          upState(loadstate);
          txtvMsg.setText(msg);
          this.upstate = refreshState;
          startUpAnimation(upstate);
        }
      }
    }
  }

  /**
   * 获取控件宽高
   *
   * @return 0为宽
   */
  public int[] getWidgetWidthAndHeight(View view) {
    int[] res = new int[2];
    int w = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    int h = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    view.measure(w, h);
    res[1] = view.getMeasuredHeight();
    res[0] = view.getMeasuredWidth();
    return res;
  }

  public void upState(int state) {
    if (currentState == state) {
      return;
    }
    currentState = state;
    switch (state) {
      case LOADING:
        imgvArrow.clearAnimation();
        imgvArrow.setVisibility(View.INVISIBLE);
        break;
      case LOAD_OVER://箭头下
        imgvArrow.startAnimation(reverseDownAnimation);
        imgvArrow.setVisibility(View.VISIBLE);
        break;
      case LOAD_BEFOR://箭头上
        imgvArrow.startAnimation(reverseUpAnimation);
        break;
    }
  }

  /**
   * 刷新成功后调用
   */
  public void loadSuccess() {
    if (upstate == LOADING)
      upRefreshState(LOAD_SUCCESS);
  }

  public void hind(boolean hind) {
    recyclerView.setVisibility(hind ? GONE : VISIBLE);
    head.setVisibility(hind ? GONE : VISIBLE);
  }


  public TransmitterState setActivity(BtManageActivity activity) {
    mActivity = activity;
    return this;
  }

  /**
   * 刷新界面
   *
   * @param searchDevice 最新搜索的射器
   */
  public synchronized void refresh(PocDeviceAndRssi searchDevice, String deviceType) {
    if (searchDevice == null) {
      mPocDeviceList.clear();
    } else {
      if (deviceType == null
        || EDevice.getEnumDevice(searchDevice.getPocDevice().getName()).getDeviceType().contains(deviceType)) {
        mPocDeviceList.add(searchDevice);
        Collections.sort(mPocDeviceList);
      }
    }
    adapter.notifyDataSetChanged();
  }

  public void notifyItem() {
    isConnecting = false;
  }


  public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

    public SpacesItemDecoration(int space) {
      this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view,
                               RecyclerView parent, RecyclerView.State state) {
      outRect.left = space;
      outRect.right = space;
      outRect.bottom = space;

      // Add top margin only for the first item to avoid double space between items
      if (parent.getChildAdapterPosition(view) == 0)
        outRect.top = space;
    }
  }

  public class SearchListAdapter extends RecyclerView.Adapter<SearchListAdapter.ViewHolder> {

    /**
     * 发射器搜索列表
     */
    private List<PocDeviceAndRssi> mPocDeviceList;

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_transmitter_list, parent, false);
      return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
      PocDeviceAndRssi device = mPocDeviceList.get(position);
      if (device != null) {
        holder.tvDeviceName.setText(device.getPocDevice().getName());
        if (device.getCheckedPostion() == position) {
          holder.tvDeviceState.setVisibility(GONE);
        } else {
          holder.tvDeviceState.setVisibility(VISIBLE);
        }
        holder.mainView.setOnClickListener(v -> {
          check(device.getPocDevice(), position);
        });
      }
    }

    public SearchListAdapter(List<PocDeviceAndRssi> list) {
      mPocDeviceList = list;
    }

    @Override
    public int getItemCount() {
      return mPocDeviceList.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
      View mainView;
      TextView tvDeviceName;
      TextView tvDeviceState;

      ViewHolder(View view) {
        super(view);
        mainView = view;
        tvDeviceName = view.findViewById(R.id.transmitter_list_name);
        tvDeviceState = view.findViewById(R.id.transmitter_list_state);
      }
    }
  }

  /**
   * 点击连接的操作
   *
   * @param device   设备
   * @param position
   */
  private void check(PocDevice device, int position) {
    if (PopupWindowManagement.getInstance().isShowing()) {
      return;
    }
    if (!Tool.isBluetoothEnabled(mActivity.getApplicationContext())) {
      return;
    }
    SharedPreferencesLibraryUtil sharedPreferencesLibraryUtil = new SharedPreferencesLibraryUtil(BApplication.getContext());
    sharedPreferencesLibraryUtil.clearQRInformation();
    if (!isConnecting) {
      connectCT1_1(device, position);
      isConnecting = true;
    }
  }

  public void connectCT1_1(PocDevice device, int position) {
    String[] message = new String[2];
    message[0] = String.format(getResources().getString(R.string.bt_connect_device_confirm), device.getName());
    message[1] = mActivity.getString(R.string.bt_connect_device_info);
    PopupWindowManagement.getInstance().setOnSelectListener(new BPopupWindow.OnSelectListener() {
      @Override
      public void confirm(View view) {
        if (onDeviceConnectionListener != null) {
          onDeviceConnectionListener.onDeviceConnect(device, position);
//                    refreshLoadingIcon(position);
        }
      }

      @Override
      public void cancel(View view) {
        isConnecting = false;
      }
    }).setMessages(message).show(mActivity, PopupType.POPUP_CONNECT_1);
  }

  public void setOnDeviceConnectionListener(OnDeviceConnectionListener
                                              onDeviceConnectionListener) {
    this.onDeviceConnectionListener = onDeviceConnectionListener;
  }

  /**
   * 点击连接的接口
   */
  public interface OnDeviceConnectionListener {
    /**
     * 点击发射器
     *
     * @param pocDevice 点击的发射器信息
     */
    void onDeviceConnect(PocDevice pocDevice, int position);

    /**
     * 进行二维码扫描
     *
     * @param type 则需要进行弹出框的消息
     */
    void onQRResult(int type, PocDevice pocDevice, int position);

  }

}
