package it.integry.integrywmsnative.core.utility;

import com.annimon.stream.Stream;

import java.util.Calendar;

import it.integry.barcode_base_android_library.model.BarcodeScanDTO;
import it.integry.barcode_base_android_library.model.BarcodeType;
import it.integry.integrywmsnative.core.model.MtbDepoPosizione;
import it.integry.integrywmsnative.core.settings.SettingsManager;

public class UtilityBarcode {


    public static boolean isBarcodeOrdineV(BarcodeScanDTO barcodeScanDTO) {
        return (isEan13(barcodeScanDTO) || isEtichetta128(barcodeScanDTO)) && barcodeScanDTO.getStringValue().startsWith("3");
    }

    public static boolean isEtichettaAnonima(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.CODE128 && barcodeScanDTO.getStringValue().startsWith("U");
    }

    public static boolean isEtichettaAnonimaOfCurrentYear(String barcode) {
        Calendar calendar = UtilityDate.getCalendarInstance();
        int currentYear = calendar.get(Calendar.YEAR);

        String fullYear = "20" + UtilityBarcode.getAnnoColloFromULAnonima(barcode);
        return fullYear.equalsIgnoreCase("" + currentYear);
    }

    public static boolean isEtichetta128(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && (barcodeScanDTO.getType() == BarcodeType.CODE128 || barcodeScanDTO.getType() == BarcodeType.EAN128);
    }

    public static boolean isEan128(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.EAN128;
    }

    public static boolean isEtichettaPosizione(BarcodeScanDTO barcodeScanDTO) {
        return isEtichettaPosizione(barcodeScanDTO, true);
    }

    public static boolean isEtichettaPosizione(BarcodeScanDTO barcodeScanDTO, boolean enableCheckCodMdep) {
        String currentCodMdep = SettingsManager.i().getUserSession().getDepo().getCodMdep();

        String barcode = barcodeScanDTO.getStringValue();
        boolean isPosizione = false;

        if (SettingsManager.iDB().getAvailablePosizioni() != null) {
            Stream<MtbDepoPosizione> tmpStream = Stream.of(SettingsManager.iDB().getAvailablePosizioni())
                    .filter(x -> x.getPosizione().equalsIgnoreCase(barcode) && (!enableCheckCodMdep || currentCodMdep.equalsIgnoreCase(x.getCodMdep())));

            if (tmpStream.count() > 0) {
                isPosizione = true;
            }
        }

        return isPosizione;
    }

    public static boolean isEtichettaArt(BarcodeScanDTO barcodeScanDTO) {
        return isEan8(barcodeScanDTO) || isEan13(barcodeScanDTO) || isUPCA(barcodeScanDTO) || isInterleaved2Of5(barcodeScanDTO);
    }


    public static boolean isEanPeso(BarcodeScanDTO barcodeScanDTO) {
        return (isEtichetta128(barcodeScanDTO) || isEan13(barcodeScanDTO)) && barcodeScanDTO.getStringValue().startsWith("2");
    }

    public static boolean isEan8(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.EAN8;
    }

    public static boolean isEan13(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.EAN13;
    }

    public static boolean isUPCA(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.UPCA;
    }

    public static boolean isInterleaved2Of5(BarcodeScanDTO barcodeScanDTO) {
        return barcodeScanDTO != null && barcodeScanDTO.getType() == BarcodeType.INTERLEAVED_2OF5;
    }


    public static Integer getNumColloFromULAnonima(String barcode) throws Exception {
        if (!UtilityString.isNullOrEmpty(barcode)) {
            barcode = barcode.trim();
            try {
                return Integer.parseInt(barcode.substring(3, 10));
            } catch (NumberFormatException nfex) {
                throw new Exception("Impossibile leggere il numero collo dal barcode: " + barcode);
            }
        } else
            return null;
    }


    public static Integer getAnnoColloFromULAnonima(String barcode) {
        if (barcode != null) {
            return Integer.parseInt(barcode.substring(1, 3));
        } else
            return null;
    }


    public static String convertITF14toEAN13(String barcodeITF14) {
        String barcodeEAN13 = null;

        if (barcodeITF14.length() == 14) {
            barcodeEAN13 = barcodeITF14.substring(1, barcodeITF14.length() - 1).trim();
            barcodeEAN13 += getEAN13CheckDigit(barcodeEAN13);
        }

        return barcodeEAN13;
    }

    public static String convertITF14toNeutral(String barcodeITF14) {
        String barcodeNeutral = null;

        if (barcodeITF14.length() == 14) {
            barcodeNeutral = barcodeITF14.substring(1, barcodeITF14.length() - 1);
        }

        return barcodeNeutral;
    }


    private static String getEAN13CheckDigit(String ean) {

        if (ean.length() != 12) {
            UtilityLogger.error(new Exception("Please provide an input string of 12 chars. Current lenght: " + ean.length()));
            return null;
        }
        long tot = 0;

        for (int i = 0; i < 12; i++) {
            tot = tot + (Long.parseLong(String.valueOf(ean.charAt(i))) * (i % 2 == 0 ? 1 : 3));
        }
        return tot % 10 == 0 ? "0" : "" + (10 - (tot % 10));
    }

}
