package com.ez.ertc.meeting.ui;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.ez.ertc.meeting.R;
import com.ez.ertc.meeting.R2;
import com.ez.ertc.meeting.base.YsBaseAdapter;
import com.ez.ertc.meeting.base.YsBaseDto;
import com.ez.ertc.meeting.base.YsCallback;
import com.ez.ertc.meeting.base.YsDtoStyle;
import com.ez.ertc.meeting.base.YsRvBaseHolder;
import com.ez.ertc.meeting.contract.BeautyConfigContract;
import com.ez.ertc.meeting.utils.BeautyUtil;
import com.ez.ertc.meeting.utils.FaceBeautyFilterEnum;
import com.ez.ertc.meeting.utils.ViewUtil;
import com.ez.ertc.meeting.widget.EZDialog;
import com.ez.ertc.meeting.widget.TextCircleImageView;
import com.google.android.material.tabs.TabLayout;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public
/**
 *
 *
 * @author xiezuoyuan
 * @time 2021/11/11 14:08
 */
class BeautyConfigHolder {
    @BindView(R2.id.viewSeekBar)
    View viewSeekBar;
    @BindView(R2.id.tabLayout)
    TabLayout tabLayout;
    @BindView(R2.id.viewPager)
    ViewPager viewPager;
    @BindView(R2.id.tvReset)
    TextView tvReset;
    private PagerAdapter pagerAdapter;
    private BeautySeekBarHolder beautySeekBarHolder;
    private RecyclerView viewBeauty,viewFilter;
    private YsBaseAdapter beautyAdapter,filterAdapter;
    private BeautyDTO selectedBeautyDTO;
    private BaseDTO selectedFilterDTO;
    private int selectedBeautyDTOIndex = -1,selectedFilterDTOIndex = -1;
    private List<YsBaseDto> listBeauty,listFilter;
    private BeautyConfigContract.Presenter mPresenter;
    private Context context;
    private OnItemSelected filterListener,beautyListener;

    public BeautyConfigHolder(View contentView, BeautyConfigContract.Presenter presenter) {
        this.mPresenter = presenter;
        ButterKnife.bind(this,contentView);
        context = contentView.getContext();
        beautySeekBarHolder = new BeautySeekBarHolder(viewSeekBar, new BeautySeekBarHolder.ProgressListener() {
            @Override
            public void onProgressChanged(int progress, BaseDTO baseDTO) {
                if (selectedBeautyDTO != null && baseDTO == selectedBeautyDTO){
                    switch (selectedBeautyDTO.beautyType){
                        case BeautyType.BLUR:
                            mPresenter.setBlurIntensity(progress);
                            break;
                        case BeautyType.COLOR:
                            mPresenter.setColorIntensity(progress);
                            break;
                        case BeautyType.RED:
                            mPresenter.setRedIntensity(progress);
                            break;
                    }
                } else if (selectedFilterDTO != null){
                    FilterDTO filterDTO = (FilterDTO) baseDTO;
                    mPresenter.setFilterIntensity(filterDTO.filterName,progress);
                }
                baseDTO.changedProgress = progress;
            }
        });
        final int topMargin = ViewUtil.dp2px(context,5);
        final String beautyTitle = context.getString(R.string.ys_mt_beauty_config_beauty);
        final String filterTitle = context.getString(R.string.ys_mt_beauty_config_filter);
        viewBeauty = (RecyclerView) View.inflate(context,R.layout.ezm_layout_item_beauty_viewpage,null);
        viewFilter = (RecyclerView) View.inflate(context,R.layout.ezm_layout_item_beauty_viewpage,null);
        viewBeauty.setLayoutManager(new GridLayoutManager(context,6));
        viewFilter.setLayoutManager(new GridLayoutManager(context,6));
        viewBeauty.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                outRect.top = topMargin;
                outRect.bottom = topMargin;
            }
        });
        viewFilter.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                outRect.top = topMargin;
                outRect.bottom = topMargin;
            }
        });
        List<YsDtoStyle> styles = new ArrayList<YsDtoStyle>(){{
            add(new YsDtoStyle(BeautyDTO.class,R.layout.ezm_layout_item_beauty,BeautyHolder.class));
            add(new YsDtoStyle(FilterDTO.class,R.layout.ezm_layout_item_filter,FilterHolder.class));
        }};
        beautyAdapter = new YsBaseAdapter(context,styles);
        filterAdapter = new YsBaseAdapter(context,styles);
        viewBeauty.setAdapter(beautyAdapter);
        viewFilter.setAdapter(filterAdapter);
        pagerAdapter = new PagerAdapter() {
            @Override
            public View instantiateItem(ViewGroup container, int position) {
                container.addView(position == 0 ? viewBeauty : viewFilter);
                return position == 0 ? viewBeauty : viewFilter;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(position == 0 ? viewBeauty : viewFilter);
            }
            @Override
            public int getCount() {
                return 2;
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return view == object;
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return position == 0 ? beautyTitle : filterTitle;
            }
        };
        viewPager.setAdapter(pagerAdapter);
        viewPager.setCurrentItem(0);
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                tvReset.setVisibility(position == 0 ? View.VISIBLE : View.GONE);
                if (position == 0 && selectedBeautyDTOIndex == 0){
                    beautySeekBarHolder.hideSeekBar();
                } else if (position == 1 && selectedFilterDTOIndex == 0){
                    beautySeekBarHolder.hideSeekBar();
                } else {
                    beautySeekBarHolder.showSeekBar();
                }
                if (position == 0 && selectedBeautyDTO != null){
                    beautySeekBarHolder.setDefaultProgress(selectedBeautyDTO);
                    beautySeekBarHolder.updateProgress(selectedBeautyDTO.changedProgress);
                } else if (position == 1 && selectedFilterDTO != null){
                    beautySeekBarHolder.setDefaultProgress(selectedFilterDTO);
                    beautySeekBarHolder.updateProgress(selectedFilterDTO.changedProgress);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        pagerAdapter.notifyDataSetChanged();
        initData();
    }
    @OnClick({R2.id.tvReset})
    public void onClick(View view){
        int id = view.getId();
        if (id == R.id.tvReset){
            new EZDialog.Builder(context)
                    .setTitle(R.string.ys_mt_beauty_config_reset_title)
                    .setMessage(R.string.ys_mt_beauty_config_reset_msg)
                    .setPositiveButton(R.string.ezm_confirm, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            BaseDTO blurDTO = null;
                            for (YsBaseDto dto : listBeauty) {
                                BeautyDTO beautyDTO = (BeautyDTO) dto;
                                switch (beautyDTO.beautyType){
                                    case BeautyType.NONE:
                                        break;
                                    case BeautyType.COLOR:
                                        int colorIntensityPercent = mPresenter.getDefaultColorIntensityPercent();
                                        beautyDTO.defaultProgress = colorIntensityPercent;
                                        beautyDTO.changedProgress = colorIntensityPercent;
                                        mPresenter.setColorIntensity(colorIntensityPercent);
                                        break;
                                    case BeautyType.RED:
                                        int redIntensityPercent = mPresenter.getDefaultRedIntensityPercent();
                                        beautyDTO.defaultProgress = redIntensityPercent;
                                        beautyDTO.changedProgress = redIntensityPercent;
                                        mPresenter.setRedIntensity(redIntensityPercent);
                                        break;
                                    case BeautyType.BLUR:
                                        blurDTO = beautyDTO;
                                        int blurIntensityPercent = mPresenter.getDefaultBlurIntensityPercent();
                                        beautyDTO.defaultProgress = blurIntensityPercent;
                                        beautyDTO.changedProgress = blurIntensityPercent;
                                        mPresenter.setBlurIntensity(blurIntensityPercent);
                                        break;
                                }
                            }
                            if (beautyListener != null){
                                beautyListener.OnItemSelected(blurDTO);
                            }
                            beautySeekBarHolder.showSeekBar();
                            beautyAdapter.notifyDataSetChanged();
                        }
                    })
                    .setNegativeButton(R.string.ezm_cancel,null)
                    .create().show();
        }
    }
    protected void initData() {
        filterListener = new OnItemSelected() {
            @Override
            public void OnItemSelected(BaseDTO dto) {
                if (dto == null){
                    return;
                }
                if (dto.selected){
                    beautySeekBarHolder.setDefaultProgress(dto);
                    beautySeekBarHolder.updateProgress(dto.changedProgress);
                }
                for (int i = 0; i < listFilter.size(); i++) {
                    YsBaseDto baseDto = listFilter.get(i);
                    if (baseDto == dto){
                        dto.selected = true;
                        filterAdapter.notifyItemChanged(i);
                        beautySeekBarHolder.setDefaultProgress(dto);
                        beautySeekBarHolder.updateProgress(dto.changedProgress);
                        if (i == 0){
                            mPresenter.setFilterIntensity(FaceBeautyFilterEnum.ORIGIN,0);
                        } else {
                            mPresenter.setFilterIntensity(((FilterDTO)dto).filterName,dto.changedProgress);
                        }
                        if (selectedFilterDTOIndex > -1){
                            selectedFilterDTO.selected = false;
                            filterAdapter.notifyItemChanged(selectedFilterDTOIndex);
                        }
                        selectedFilterDTO = dto;
                        selectedFilterDTOIndex = i;
                        break;
                    }
                }
            }
        };
        beautyListener = new OnItemSelected() {
            @Override
            public void OnItemSelected(BaseDTO dto) {
                if (dto == null){
                    return;
                }
                if (dto.selected){
                    beautySeekBarHolder.setDefaultProgress(dto);
                    beautySeekBarHolder.updateProgress(dto.changedProgress);
                }
                for (int i = 0; i < listBeauty.size(); i++) {
                    YsBaseDto baseDto = listBeauty.get(i);
                    if (baseDto == dto){
                        //LG.i("OnItemSelected=="+context.getString((Integer) dto.getData()));
                        dto.selected = true;
                        beautyAdapter.notifyItemChanged(i);
                        beautySeekBarHolder.setDefaultProgress(dto);
                        beautySeekBarHolder.updateProgress(dto.changedProgress);
                        BeautyDTO beautyDTO = (BeautyDTO) dto;
                        mPresenter.setSelectedBeautyType(beautyDTO.beautyType);
                        switch (beautyDTO.beautyType){
                            case BeautyType.NONE:
                                //选择“无”，清空其他美颜效果
                                mPresenter.setNoIntensity();
                                for (YsBaseDto ysBaseDto : listBeauty) {
                                    BeautyDTO dto1 = (BeautyDTO) ysBaseDto;
                                    if (dto1.beautyType != BeautyType.NONE){
                                        dto1.changedProgress = 0;
                                    }
                                }
                                break;
                                case BeautyType.BLUR:
                                    mPresenter.setBlurIntensity(dto.changedProgress);
                                    break;
                            case BeautyType.COLOR:
                                    mPresenter.setColorIntensity(dto.changedProgress);
                                    break;
                            case BeautyType.RED:
                                    mPresenter.setRedIntensity(dto.changedProgress);
                                    break;
                        }
                        if (selectedBeautyDTOIndex > -1 && selectedBeautyDTO != null){
                            //LG.i("OnItemSelected==old=="+context.getString((Integer) selectedBeautyDTO.getData()));
                            selectedBeautyDTO.selected = false;
                            beautyAdapter.notifyItemChanged(selectedBeautyDTOIndex);
                        }
                        selectedBeautyDTO = (BeautyDTO) dto;
                        selectedBeautyDTO.selected = true;
                        selectedBeautyDTOIndex = i;
                        break;
                    }
                }
            }
        };
        beautyAdapter.update(listBeauty = BeautyUtil.generateBeautyDTO(mPresenter,beautyListener));
        for (int i = 0; i < listBeauty.size(); i++) {
            BaseDTO dto = (BaseDTO)listBeauty.get(i);
            if (dto.selected){
                //LG.i("selectedBeautyDTO=="+context.getString((Integer) dto.getData())+
                //        " defaultProgress:"+dto.defaultProgress+
                //        " changedProgress:"+dto.changedProgress);
                beautySeekBarHolder.setDefaultProgress(dto);
                beautySeekBarHolder.updateProgress(dto.changedProgress);
                selectedBeautyDTO = (BeautyDTO) dto;
//                selectedBeautyDTOIndex = i;
                ((BeautyDTO) dto).onItemSelected.OnItemSelected(dto);
                break;
            }
        }
        //在工作线程中生成滤镜数据
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                final String cachedFilterName = mPresenter.getCachedFilterName();
                final int cachedFilterPercent = mPresenter.getCachedFilterPercent();
                listFilter = BeautyUtil.generateFilterDTO(40,cachedFilterPercent,cachedFilterName,filterListener);
                for (int i = 0; i < listFilter.size(); i++) {
                    BaseDTO dto = (BaseDTO)listFilter.get(i);
                    if (dto.selected){
                        //LG.i("selectedFilterDTO=="+context.getString((Integer) dto.getData())+
                        //        " defaultProgress:"+dto.defaultProgress+
                        //        " changedProgress:"+dto.changedProgress);
                        selectedFilterDTO = (BaseDTO) dto;
                        selectedFilterDTOIndex = i;
                        break;
                    }
                }
                emitter.onNext(listFilter);
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new YsCallback<Object>() {
                    @Override
                    public void onNext(@NonNull Object o) {
                        filterAdapter.update(listFilter);
                    }
                });
    }
    public void onShow(){
        beautySeekBarHolder.onShow();
    }
    public static class BaseDTO extends YsBaseDto<Integer> {
        public int defaultProgress;//-1表示“无”，不显示seekbar
        public int changedProgress;
        public boolean selected = false;
        public BaseDTO(Integer nameId, int defaultProgress, boolean selected) {
            super(nameId);
            this.defaultProgress = defaultProgress;
            this.selected = selected;
            changedProgress = defaultProgress;
        }
    }
    public static class BeautyDTO extends BaseDTO {
        public int resId;
        public int beautyType;
        public OnItemSelected onItemSelected;

        public BeautyDTO(Integer nameId, int resId, int defaultProgress,int beautyType, boolean selected, OnItemSelected onItemSelected) {
            super(nameId,defaultProgress,selected);
            this.resId = resId;
            this.beautyType = beautyType;
            this.onItemSelected = onItemSelected;
        }

    }
    public static class BeautyHolder extends YsRvBaseHolder<BeautyDTO> {
        @BindView(R2.id.flItem)
        FrameLayout flItem;
        @BindView(R2.id.ivItem)
        ImageView ivItem;
        @BindView(R2.id.tvItem)
        TextView tvItem;
        private BeautyDTO beautyDTO;
        public BeautyHolder(View itemView, Context context) {
            super(itemView, context);
            ButterKnife.bind(this,itemView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    beautyDTO.onItemSelected.OnItemSelected(beautyDTO);
                }
            });
        }

        @Override
        public void setData(BeautyDTO beautyDTO) {
            this.beautyDTO = beautyDTO;
            flItem.setSelected(beautyDTO.selected);
            tvItem.setSelected(beautyDTO.selected);
            ivItem.setImageResource(beautyDTO.resId);
            tvItem.setText(beautyDTO.getData());
        }
    }
    public static class FilterDTO extends BaseDTO {
        public String filterName;
        public int resId;
        public OnItemSelected onItemSelected;

        public FilterDTO(Integer nameId, int resId,int defaultProgress,String filterName, boolean selected, OnItemSelected onItemSelected) {
            super(nameId, defaultProgress, selected);
            this.filterName = filterName;
            this.resId = resId;
            this.onItemSelected = onItemSelected;
        }
    }
    public static class FilterHolder extends YsRvBaseHolder<FilterDTO> {

        @BindView(R2.id.ivBg)
        ImageView ivBg;
        @BindView(R2.id.ivItem)
        TextCircleImageView ivItem;
        @BindView(R2.id.tvItem)
        TextView tvItem;
        private FilterDTO filterDTO;
        public FilterHolder(View itemView, Context context) {
            super(itemView, context);
            ButterKnife.bind(this,itemView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    filterDTO.onItemSelected.OnItemSelected(filterDTO);
                }
            });
        }

        @Override
        public void setData(FilterDTO filterDTO) {
            this.filterDTO = filterDTO;
            ivItem.setImageResource(filterDTO.resId);
            tvItem.setText(filterDTO.getData());
            ivBg.setSelected(filterDTO.selected);
            tvItem.setSelected(filterDTO.selected);
        }
    }
    public interface OnItemSelected {
        void OnItemSelected(BaseDTO dto);
    }
    public class BeautyType {
        public static final int NONE = 0;
        public static final int COLOR = 1;
        public static final int RED = 2;
        public static final int BLUR = 3;
    }
}
