package com.ihaoin.hooloo.device.view;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.ihaoin.hooloo.device.HLApplication;
import com.ihaoin.hooloo.device.R;
import com.ihaoin.hooloo.device.adapter.TrolleyAdapter;
import com.ihaoin.hooloo.device.component.NetworkHandler;
import com.ihaoin.hooloo.device.config.Base;
import com.ihaoin.hooloo.device.data.TrolleyGoods;
import com.ihaoin.hooloo.device.data.vo.Goods;
import com.ihaoin.hooloo.device.data.vo.Sku;
import com.ihaoin.hooloo.device.network.HttpUtil;
import com.ihaoin.hooloo.device.util.RandomUtils;
import com.ihaoin.hooloo.device.util.Utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class TrolleyView extends RelativeLayout {
    private List<TrolleyGoods> trolleyGoods = new ArrayList<>();
    private Boolean state = false;
    private Boolean trolleyAniming = false;

    private View butnClear;
    private View viewBackground;
    private View layoutTrolley;
    private ListView listTrolley;
    private View layoutSettleBar;
    private TextView txtCount;
    private TextView txtTotal;
    private View butnPay;

    TrolleyAdapter trolleyAdapter;

    private void init() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.view_trolley, this);

        butnClear = view.findViewById(R.id.butn_clear);
        viewBackground = view.findViewById(R.id.view_background);
        layoutTrolley = view.findViewById(R.id.layout_trolley);
        listTrolley = view.findViewById(R.id.list_trolley);
        layoutSettleBar = view.findViewById(R.id.layout_settle_bar);
        txtCount = view.findViewById(R.id.txt_count);
        txtTotal = view.findViewById(R.id.txt_total);
        butnPay = view.findViewById(R.id.butn_pay);
        this.setView();

        trolleyAdapter = new TrolleyAdapter(this.getContext(), this);
        listTrolley.setAdapter(trolleyAdapter);

        butnClear.setOnClickListener(v -> clearTrolley());
        layoutSettleBar.setOnClickListener(v -> toggleTrolley());
        viewBackground.setOnClickListener(v -> closeTrolley());

        butnPay.setOnClickListener(v -> showPayDialog());
    }

    public void prepareAddGoods(Goods goods, Sku sku, Integer count) {
        CheckGoodsHandler handler = new CheckGoodsHandler(goods, sku, count);
        HttpUtil.checkSku(sku.getSkuId(), handler);
    }

    class CheckGoodsHandler extends NetworkHandler {
        private Goods goods;
        private Sku sku;
        private Integer count;

        public CheckGoodsHandler(Goods goods, Sku sku, Integer count) {
            super();
            this.goods = goods;
            this.sku = sku;
            this.count = count;
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what != 1) {
                Toast.makeText(getContext(), ((Exception) msg.obj).getMessage(), Toast.LENGTH_SHORT).show();
                return;
            }
            addGoods(goods, sku, count);
        }
    }

    private Integer getCountOfOrder() {
        if (HLApplication.getMainData() == null || HLApplication.getMainData().getCountOfOrder() == null) {
            return 9;
        }
        return HLApplication.getMainData().getCountOfOrder();
    }

    /** 添加商品到购物车 - 商品详情、商品列表 */
    public void addGoods(Goods goods, Sku sku, Integer count) {
//        if (!checkSkuState(sku.getSkuId())) {
//            Toast.makeText(this.getContext(), R.string.error_sku_state, Toast.LENGTH_SHORT).show();
//            return;
//        }
        if (getCount() >= getCountOfOrder()) {
            Toast.makeText(this.getContext(), getContext().getString(R.string.count_limit, getCountOfOrder().toString()), Toast.LENGTH_SHORT).show();
            return;
        }
        Optional<TrolleyGoods> optional = this.trolleyGoods.stream().filter(x -> x.getGoodId().equals(goods.getGoodsId()) && x.getSkuId().equals(sku.getSkuId())).findAny();
        // 判断是否在购物车里存在同样规格的产品
        if (optional.isPresent()) {
            TrolleyGoods g = optional.get();
            g.setCount(g.getCount() + count);
        } else {
            TrolleyGoods g = new TrolleyGoods();
            g.setId(RandomUtils.nextLong(trolleyGoods.stream().map(TrolleyGoods::getId).collect(Collectors.toList())));
            g.setChecked(true);
            g.setGoodId(goods.getGoodsId());
            g.setName(goods.getName());
            g.setDesc(goods.getDesc());
            g.setPics(goods.getPics());
            g.setTags(goods.getTags());
            g.setSkuId(sku.getSkuId());
            g.setState(sku.getState());
            g.setIsDefault(sku.getIsDefault());
            g.setPrice(sku.getPrice());
            g.setDiscount(sku.getDiscount());
            g.setRules(sku.getRules());
            g.setCount(count);
            this.trolleyGoods.add(g);
        }

        this.goodsChanged();
    }

    /** 购物车商品增加数量 */
    public void addGoods(Integer position) {
//        if (!checkSkuState(goods.getSkuId())) {
//            Toast.makeText(this.getContext(), R.string.error_sku_state, Toast.LENGTH_SHORT).show();
//            return;
//        }
        if (getCount() >= getCountOfOrder()) {
            Toast.makeText(this.getContext(), getContext().getString(R.string.count_limit, getCountOfOrder().toString()), Toast.LENGTH_SHORT).show();
            return;
        }
        TrolleyGoods goods = this.trolleyGoods.get(position);
        goods.setCount(goods.getCount() + 1);
        this.goodsChanged();
    }

    /** 购物车商品减少数量 */
    public void subtractGoods(Integer position) {
        TrolleyGoods goods = this.trolleyGoods.get(position);
        if (goods.getCount() <= 1) {
            this.trolleyGoods.remove(goods);
        } else {
            goods.setCount(goods.getCount() - 1);
        }
        this.goodsChanged();
    }

    public void goodsChanged() {
        this.trolleyAdapter.notifyDataSetChanged();
        this.txtCount.setText(getCheckedCount().toString());
        this.txtTotal.setText(Utils.toString(getCheckedTotal()));
        this.setView();
        this.measureListHeight();
    }

    public Boolean checkGoodsCount() {
        if (getCount() > getCountOfOrder()) {
            Toast.makeText(this.getContext(), getContext().getString(R.string.count_limit, getCountOfOrder().toString()), Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    private Integer getCount() {
        return this.getTrolleyGoods().stream().mapToInt(TrolleyGoods::getCount).sum();
    }

    private Integer getCheckedCount() {
        return this.getTrolleyGoods().stream().filter(TrolleyGoods::getChecked).mapToInt(TrolleyGoods::getCount).sum();
    }

    private BigDecimal getTotal() {
        return this.getTrolleyGoods().stream().map(x -> x.getDiscount().multiply(new BigDecimal(x.getCount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private BigDecimal getCheckedTotal() {
        return this.getTrolleyGoods().stream().filter(TrolleyGoods::getChecked).map(x -> x.getDiscount().multiply(new BigDecimal(x.getCount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private void setView() {
        if (this.trolleyGoods.isEmpty()) {
            this.setVisibility(View.INVISIBLE);
            viewBackground.setVisibility(View.INVISIBLE);
            layoutTrolley.setVisibility(View.INVISIBLE);
            state = false;
            Utils.fastBroadcast(getContext(), Base.BROADCAST_ACTION_TROLLEY_HIDE);
        } else {
            this.setVisibility(View.VISIBLE);
            Utils.fastBroadcast(getContext(), Base.BROADCAST_ACTION_TROLLEY_SHOW);
        }
    }

    private void measureListHeight() {
        int count = this.trolleyGoods.size() > 3 ? 3 : this.trolleyGoods.size();
        int height = Utils.getDimens(this.getContext(), R.dimen.trolley_item_height) * count;
        ViewGroup.LayoutParams layoutParams = listTrolley.getLayoutParams();
        layoutParams.height = height;
        listTrolley.setLayoutParams(layoutParams);
    }

    public void clearTrolley() {
        this.trolleyGoods.clear();
        setView();
    }

    private void toggleTrolley() {
        if (state) {
            closeTrolley();
        } else {
            openTrolley();
        }
    }


    private void openTrolley() {
        if (trolleyAniming) {
            return;
        }
        trolleyAniming = true;
        viewBackground.setOnClickListener(v -> closeTrolley());
        layoutTrolley.setOnClickListener(v -> {
        });
        viewBackground.setVisibility(View.VISIBLE);
        layoutTrolley.setVisibility(View.VISIBLE);

        Animation animation = AnimationUtils.loadAnimation(this.getContext(), R.anim.trolley_translate_in);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                trolleyAniming = false;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        layoutTrolley.startAnimation(animation);
        state = true;
    }

    private void closeTrolley() {
        if (trolleyAniming) {
            return;
        }
        trolleyAniming = true;
        Animation animation = AnimationUtils.loadAnimation(this.getContext(), R.anim.trolley_translate_out);
        layoutTrolley.startAnimation(animation);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                viewBackground.setVisibility(View.INVISIBLE);
                layoutTrolley.setVisibility(View.INVISIBLE);
                state = false;
                trolleyAniming = false;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
    }

    private void showPayDialog() {
        if (getCheckedCount() <= 0) {
            Toast.makeText(getContext(), R.string.error_choose_goods, Toast.LENGTH_LONG).show();
            return;
        }
        if (getCheckedTotal().compareTo(BigDecimal.ZERO) < 0) {
            Toast.makeText(getContext(), R.string.error_price, Toast.LENGTH_LONG).show();
            return;
        }

        Utils.showConfirmOrder(getContext(), trolleyGoods);
    }

    class CheckSkuStateHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {

        }
    }

    public TrolleyView(Context context) {
        super(context);
        init();
    }

    public TrolleyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TrolleyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public TrolleyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public List<TrolleyGoods> getTrolleyGoods() {
        return trolleyGoods;
    }
}
