package it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.core;

import android.content.Context;
import androidx.databinding.ObservableArrayList;
import android.view.View;

import com.annimon.stream.Stream;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.CommonConst;
import it.integry.integrywmsnative.core.model.MtbColr;
import it.integry.integrywmsnative.gest.accettazione.dto.OrdineAccettazioneDTO;
import it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.dto.AccettazioneOrdineInevasoListViewModel;
import it.integry.integrywmsnative.gest.accettazione_ordine_inevaso.dto.AccettazioneOrdineInevasoOrderBy;

/**
 * Created by GiuseppeS on 21/03/2018.
 */

public class AccettazioneOrdineInevasoHelper {

    private Context mContext;

    private ObservableArrayList<AccettazioneOrdineInevasoListViewModel> mListViewModels = new ObservableArrayList<>();

    public AccettazioneOrdineInevasoHelper(Context context){
        mContext = context;
    }

    public MainListOrdineAccettazioneAdapter getRightListAdapter(View emptyView) {
        return new MainListOrdineAccettazioneAdapter(mContext, mListViewModels, emptyView);
    }

    public void updateListModel(AccettazioneOrdineInevasoOrderBy.Enum orderByEnum, List<List<OrdineAccettazioneDTO.Riga>> mDataset, List<MtbColr> mtbColrs) throws Exception {

        mListViewModels.clear();

        switch (orderByEnum){
            case COD_ART_FOR:
            case DESCR_ART:
                mListViewModels.addAll(getListViewModelPerArtForn(mDataset, mtbColrs));
                break;

            case RAG_SOC_COM:
                mListViewModels.addAll(getListViewModelPerRagSocCommessa(mDataset, mtbColrs));
                break;

            default:
                throw new Exception("Cannot find right list adapter: " + orderByEnum.toString());
        }

    }


    public List<List<OrdineAccettazioneDTO.Riga>> getOrdiniRaggruppatiPerCodArtForn(List<OrdineAccettazioneDTO.Riga> mDataset, boolean forceHiddenCheck){
        List<String> codArtForns = new ArrayList<>();

        for(int i = 0; i < mDataset.size(); i++){
            if(!codArtForns.contains(mDataset.get(i).codArtFor)){
                codArtForns.add(mDataset.get(i).codArtFor);
            }

            if(mDataset.get(i).codJcom == null) mDataset.get(i).codJcom = CommonConst.Config.COMMESSA_MAG;
            if(mDataset.get(i).codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)) mDataset.get(i).descrizioneCommessa = null;
        }

        boolean anyNull = codArtForns.contains(null);

        codArtForns = Stream.of(codArtForns)
                .withoutNulls()
                .sortBy(x -> x).toList();

        if(anyNull) codArtForns.add(null);


        List<List<OrdineAccettazioneDTO.Riga>> groupedRighe = new ArrayList<>();
        for (String codArtForn : codArtForns) {

            List<OrdineAccettazioneDTO.Riga> tmpList = Stream.of(mDataset).filter(x -> x.getCodArtFor() != null && x.getCodArtFor().equalsIgnoreCase(codArtForn)).toList();

            for(int i = 0; i < tmpList.size(); i++){
                if(tmpList.get(i).isHidden() == null || forceHiddenCheck) {
                    if (tmpList.get(i).getQtaDaEvadere().floatValue() <= 0) {
                        tmpList.get(i).setHidden(true);
                        //tmpList.remove(i);
                        //i--;
                    } else tmpList.get(i).setHidden(false);


                    tmpList.get(i).setTempHidden(false);
                }
            }

            if(tmpList.size() > 0){
                groupedRighe.add(tmpList);
            }
        }

        return groupedRighe;
    }


    public List<List<OrdineAccettazioneDTO.Riga>> getOrdiniRaggruppatiPerDescrArt(List<OrdineAccettazioneDTO.Riga> mDataset, boolean forceHiddenCheck){
        List<String> descrArtForns = new ArrayList<>();

        for(int i = 0; i < mDataset.size(); i++){
            if(!descrArtForns.contains(mDataset.get(i).descrizioneEstesa)){
                descrArtForns.add(mDataset.get(i).descrizioneEstesa);
            }

            if(mDataset.get(i).codJcom == null) mDataset.get(i).codJcom = CommonConst.Config.COMMESSA_MAG;
            if(mDataset.get(i).codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)) mDataset.get(i).descrizioneCommessa = null;
        }

        Collections.sort(descrArtForns, String::compareToIgnoreCase);

        List<List<OrdineAccettazioneDTO.Riga>> groupedRighe = new ArrayList<>();
        for (String descrArtForn : descrArtForns) {
            List<OrdineAccettazioneDTO.Riga> tmpList = Stream.of(mDataset).filter(x -> x.getDescrizioneEstesa() != null && x.getDescrizioneEstesa().equalsIgnoreCase(descrArtForn)).toList();

            for(int i = 0; i < tmpList.size(); i++){
                if(tmpList.get(i).isHidden() == null || forceHiddenCheck) {
                    if (tmpList.get(i).getQtaDaEvadere().floatValue() <= 0) {
                        tmpList.get(i).setHidden(true);
                        //tmpList.remove(i);
                        //i--;
                    } else tmpList.get(i).setHidden(false);


                    tmpList.get(i).setTempHidden(false);
                }
            }

            if(tmpList.size() > 0){
                groupedRighe.add(tmpList);
            }
        }

        return groupedRighe;
    }


    private class RaggruppaPerCommessaUtilDTO {
        public String codJcom = "";
        public String ragSocCom = "";
    }

    public List<List<OrdineAccettazioneDTO.Riga>> getOrdiniRaggruppatiPerRagSocCommessa(List<OrdineAccettazioneDTO.Riga> mDataset, boolean forceHiddenCheck) {
        List<RaggruppaPerCommessaUtilDTO> commessaList = new ArrayList<>();

        commessaList.add(new RaggruppaPerCommessaUtilDTO());

        for(int i = 0; i < mDataset.size(); i++){
            boolean alreadyExists = false;

            if(mDataset.get(i).codJcom == null) mDataset.get(i).codJcom = CommonConst.Config.COMMESSA_MAG;
            if(mDataset.get(i).codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)) mDataset.get(i).descrizioneCommessa = mContext.getText(R.string.stock).toString().toUpperCase();


            for(int k = 0; k < commessaList.size(); k++){
                if(commessaList.get(k).codJcom.equalsIgnoreCase(mDataset.get(i).codJcom)){
                    alreadyExists = true;
                }
            }

            if(mDataset.get(i).codJcom != null && !alreadyExists){
                RaggruppaPerCommessaUtilDTO dto = new RaggruppaPerCommessaUtilDTO();
                dto.codJcom = mDataset.get(i).codJcom;
                dto.ragSocCom = mDataset.get(i).descrizioneCommessa;
                commessaList.add(dto);
            }
        }

        Collections.sort(commessaList, (dto1, dto2) -> {
            if(dto1.ragSocCom == null || dto2.codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)) return -1;
            if(dto2.ragSocCom == null || dto1.codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)) return 1;

            return dto1.ragSocCom.compareToIgnoreCase(dto2.ragSocCom);
        });

        List<List<OrdineAccettazioneDTO.Riga>> groupedRighe = new ArrayList<>();

        for (RaggruppaPerCommessaUtilDTO dto : commessaList) {

            List<OrdineAccettazioneDTO.Riga> tmpList = Stream.of(mDataset).filter(x -> x.getCodJcom().equalsIgnoreCase(dto.codJcom)).toList();

            for(int i = 0; i < tmpList.size(); i++){
                if(tmpList.get(i).isHidden() == null || forceHiddenCheck) {
                    if (tmpList.get(i).getQtaDaEvadere().floatValue() <= 0) {
                        tmpList.get(i).setHidden(true);
                        //tmpList.remove(i);
                        //i--;
                    } else tmpList.get(i).setHidden(false);

                    tmpList.get(i).setTempHidden(false);
                }
            }

            Collections.sort(tmpList, (obj1, obj2) -> obj1.mtbAart.getDescrizioneEstesa().compareToIgnoreCase(obj2.mtbAart.getDescrizioneEstesa()));

            if(tmpList.size() > 0){
                groupedRighe.add(tmpList);
            }

        }

        return groupedRighe;
    }


    public List<AccettazioneOrdineInevasoListViewModel> getListViewModelPerArtForn(List<List<OrdineAccettazioneDTO.Riga>> groupedRighe, List<MtbColr> mtbColrs){

        List<AccettazioneOrdineInevasoListViewModel> listModel = new ArrayList<>();

        for(int i = 0; i < groupedRighe.size(); i++){
            AccettazioneOrdineInevasoListViewModel itemModel = new AccettazioneOrdineInevasoListViewModel();

            itemModel.descrizioneGroup = groupedRighe.get(i).get(0).codArtFor + " - " + groupedRighe.get(i).get(0).descrizioneEstesa;

            itemModel.rows = new ArrayList<>();

            for(int k = 0; k < groupedRighe.get(i).size(); k++){
                final OrdineAccettazioneDTO.Riga rowItem = groupedRighe.get(i).get(k);
                final AccettazioneOrdineInevasoListViewModel.SubItem rowModel = new AccettazioneOrdineInevasoListViewModel.SubItem();

                rowModel.setBadge1(rowItem.codJcom != null ? rowItem.codJcom : CommonConst.Config.COMMESSA_MAG);
                rowModel.setBadge2(String.valueOf(rowItem.numOrd));

//                rowModel.descrizione = rowItem.ragSocCom;
                rowModel.setDescrizione(rowItem.descrizioneCommessa);

                rowModel.setQtaRiservata(getRigaQuantityEvasa(rowItem, mtbColrs));
                rowModel.setQtaOrdinata(rowItem.getQtaOrd());

                rowModel.setOriginalModel(rowItem);

                itemModel.rows.add(rowModel);
            }
            listModel.add(itemModel);
        }

        return listModel;
    }


    public List<AccettazioneOrdineInevasoListViewModel> getListViewModelPerRagSocCommessa(List<List<OrdineAccettazioneDTO.Riga>> groupedRighe, List<MtbColr> mtbColrs) {
        List<AccettazioneOrdineInevasoListViewModel> listModel = new ArrayList<>();

        for(int i = 0; i < groupedRighe.size(); i++){
            AccettazioneOrdineInevasoListViewModel itemModel = new AccettazioneOrdineInevasoListViewModel();

            if(groupedRighe.get(i).get(0).codJcom.equalsIgnoreCase(CommonConst.Config.COMMESSA_MAG)){
                itemModel.descrizioneGroup = mContext.getString(R.string.warehouse).toUpperCase();
            } else {
                itemModel.descrizioneGroup = groupedRighe.get(i).get(0).codJcom;
            }

            if(groupedRighe.get(i).get(0).ragSocCom != null && groupedRighe.get(i).get(0).ragSocCom.trim().length() > 0){
                itemModel.descrizioneGroup += " - " + groupedRighe.get(i).get(0).descrizioneCommessa;
            }

            itemModel.rows = new ArrayList<>();

            for(int k = 0; k < groupedRighe.get(i).size(); k++){
                final OrdineAccettazioneDTO.Riga rowItem = groupedRighe.get(i).get(k);
                final AccettazioneOrdineInevasoListViewModel.SubItem rowModel = new AccettazioneOrdineInevasoListViewModel.SubItem();

                rowModel.setBadge1(rowItem.codArtFor);
                rowModel.setBadge2(String.valueOf(rowItem.numOrd));

                rowModel.setDescrizione(rowItem.mtbAart.getDescrizioneEstesa());

                rowModel.setQtaRiservata(getRigaQuantityEvasa(rowItem, mtbColrs));
//                rowModel.qtaRiservata = decimalFormat.format(rowItem.qtaRiservate);
                rowModel.setQtaOrdinata(rowItem.getQtaOrd());

                rowModel.setOriginalModel(rowItem);

                itemModel.rows.add(rowModel);
            }
            listModel.add(itemModel);
        }

        return listModel;
    }



    private BigDecimal getRigaQuantityEvasa(OrdineAccettazioneDTO.Riga item, List<MtbColr> mtbColrs){
        BigDecimal currentQtaEvasa = item.getQtaRiservate().add(item.getQtaEvasa());

        if(mtbColrs != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            List<MtbColr> filteredMtbColrs = Stream.of(mtbColrs)
                    .filter(x -> x.getNumOrd() != null)
                    .filter(
                       x -> x.getCodMart().equalsIgnoreCase(item.mtbAart.getCodMart()) &&
                           (x.getCodJcom() != null && x.getCodJcom().equalsIgnoreCase(item.codJcom)) &&
                            x.getRigaOrd() == item.rigaOrd &&
                            x.getNumOrd() == item.numOrd &&
                            x.getDataOrdS().equals(sdf.format(item.getDataOrd()))).toList();


            for (MtbColr mtbColr : filteredMtbColrs) {
                currentQtaEvasa = currentQtaEvasa.add(mtbColr.getQtaCol());
            }
        }

        return currentQtaEvasa;
    }
}
