package in.techware.carrefour.dbUtils.repositories;

import android.os.AsyncTask;

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

import in.techware.carrefour.dbUtils.CarrefourRoomDatabase;
import in.techware.carrefour.dbUtils.dao.PrintLabelDao;
import in.techware.carrefour.dbUtils.entity.PrintLabelEntity;
import in.techware.carrefour.model.PrintLabelBean;

/**
 * Created by Jemsheer K D on 25 July, 2018.
 * Package in.techware.carrefour.dbUtils.repositories
 * Project Carrefour
 */
public class PrintLabelRepository {

    private static PrintLabelRepository instance;


    public static PrintLabelRepository getInstance() {
        if (instance == null) {
            synchronized (CarrefourRoomDatabase.class) {
                if (instance == null) {
                    instance = new PrintLabelRepository();
                }
            }
        }
        return instance;
    }

    public void insertPrintLabel(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
        InsertPrintLabelTask insertPrintLabelTask = new InsertPrintLabelTask(printLabelBean, listener);
        insertPrintLabelTask.execute();

    }

    public void updatePrintLabel(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
        UpdatePrintLabelTask updatePrintLabelTask = new UpdatePrintLabelTask(printLabelBean, listener);
        updatePrintLabelTask.execute();

    }

    public void deletePrintLabel(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
        DeletePrintLabelTask deletePrintLabelTask = new DeletePrintLabelTask(printLabelBean, listener);
        deletePrintLabelTask.execute();

    }

    public void getAllPrintLabels(PrintLabelRepositoryListener listener) {
        GetAllPrintLabelTask getAllPrintLabelTask = new GetAllPrintLabelTask(listener);
        getAllPrintLabelTask.execute();

    }

    public void getAllUnsentPrintLabels(int labelType, PrintLabelRepositoryListener listener) {
        GetAllUnsentPrintLabelTask getAllUnsentPrintLabelTask = new GetAllUnsentPrintLabelTask(labelType, listener);
        getAllUnsentPrintLabelTask.execute();

    }

    public void getAllUnsentPrintLabels(PrintLabelRepositoryListener listener) {
        GetAllUnsentPrintLabelTask getAllUnsentPrintLabelTask = new GetAllUnsentPrintLabelTask(listener);
        getAllUnsentPrintLabelTask.execute();

    }

    public void getAllSentPrintLabels(int labelType, PrintLabelRepositoryListener listener) {
        GetAllSentPrintLabelTask getAllSentPrintLabelTask = new GetAllSentPrintLabelTask(labelType, listener);
        getAllSentPrintLabelTask.execute();

    }

    public void getAllSentPrintLabels(PrintLabelRepositoryListener listener) {
        GetAllSentPrintLabelTask getAllSentPrintLabelTask = new GetAllSentPrintLabelTask(listener);
        getAllSentPrintLabelTask.execute();

    }

    public void getPrintLabel(String printLabelID, PrintLabelRepositoryListener listener) {
        GetPrintLabelTask getPrintLabelTask = new GetPrintLabelTask(printLabelID, listener);
        getPrintLabelTask.execute();

    }

    public void deleteAllPrintLabels(PrintLabelRepositoryListener listener) {
        DeleteAllPrintLabelTask deleteAllPrintLabelTask = new DeleteAllPrintLabelTask(listener);
        deleteAllPrintLabelTask.execute();

    }

    public void deleteAllUnsentPrintLabels(int labelType, PrintLabelRepositoryListener listener) {
        DeleteAllUnsentPrintLabelTask deleteAllUnsentPrintLabelTask = new DeleteAllUnsentPrintLabelTask(labelType, listener);
        deleteAllUnsentPrintLabelTask.execute();

    }

    public void deleteAllUnsentPrintLabels(PrintLabelRepositoryListener listener) {
        DeleteAllUnsentPrintLabelTask deleteAllUnsentPrintLabelTask = new DeleteAllUnsentPrintLabelTask(listener);
        deleteAllUnsentPrintLabelTask.execute();

    }

    public void deleteAllSentPrintLabels(String key, int labelType, PrintLabelRepositoryListener listener) {
        DeleteAllSentPrintLabelTask deleteAllSentPrintLabelTask = new DeleteAllSentPrintLabelTask(key, labelType, listener);
        deleteAllSentPrintLabelTask.execute();

    }

    public void deleteAllSentPrintLabels(PrintLabelRepositoryListener listener) {
        DeleteAllSentPrintLabelTask deleteAllSentPrintLabelTask = new DeleteAllSentPrintLabelTask(listener);
        deleteAllSentPrintLabelTask.execute();

    }

    private static class InsertPrintLabelTask extends AsyncTask<String, Integer, Long> {
        private final PrintLabelBean printLabelBean;
        private final PrintLabelRepositoryListener listener;

        public InsertPrintLabelTask(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
            super();
            this.printLabelBean = printLabelBean;
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(String... params) {
            //System.out.println(">>>>>>>>>doInBackground");
            PrintLabelEntity printLabelEntity = new PrintLabelEntity(printLabelBean);
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            long id = printLabelDao.insert(printLabelEntity);
            return id;
        }

        @Override
        protected void onPostExecute(Long id) {
            super.onPostExecute(id);
            if (id != -1) {
                printLabelBean.setId(id);
                listener.onAddCompleted(printLabelBean);
            } else
                listener.onFailed();
        }
    }

    private static class UpdatePrintLabelTask extends AsyncTask<String, Integer, Boolean> {
        private final PrintLabelBean printLabelBean;
        private final PrintLabelRepositoryListener listener;

        public UpdatePrintLabelTask(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
            super();
            this.printLabelBean = printLabelBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelEntity printLabelEntity = new PrintLabelEntity(printLabelBean);
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            printLabelDao.update(printLabelEntity);
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result)
                listener.onUpdateCompleted(printLabelBean);
            else
                listener.onFailed();
        }
    }

    private static class DeletePrintLabelTask extends AsyncTask<String, Integer, Boolean> {
        private final PrintLabelBean printLabelBean;
        private final PrintLabelRepositoryListener listener;

        public DeletePrintLabelTask(PrintLabelBean printLabelBean, PrintLabelRepositoryListener listener) {
            super();
            this.printLabelBean = printLabelBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelEntity printLabelEntity = new PrintLabelEntity(printLabelBean);
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            printLabelDao.delete(printLabelEntity);
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result)
                listener.onDeleteCompleted(printLabelBean);
            else
                listener.onFailed();
        }
    }

    private static class GetAllPrintLabelTask extends AsyncTask<String, Integer, ArrayList<PrintLabelBean>> {
        private final PrintLabelRepositoryListener listener;

        public GetAllPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<PrintLabelBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            List<PrintLabelEntity> printLabelEntities = printLabelDao.loadAllPrintLabels();
            ArrayList<PrintLabelBean> printLabelList = new ArrayList<>();
            for (PrintLabelEntity phonePrintLabelEntity : printLabelEntities) {
                PrintLabelBean printLabelBean = phonePrintLabelEntity.getBean();
                printLabelList.add(printLabelBean);
            }
            return printLabelList;
        }

        @Override
        protected void onPostExecute(ArrayList<PrintLabelBean> result) {
            super.onPostExecute(result);
            if (result != null) {
                listener.onAllListLoaded(result);
            } else
                listener.onFailed();
        }
    }

    private static class GetAllUnsentPrintLabelTask extends AsyncTask<String, Integer, ArrayList<PrintLabelBean>> {
        private final PrintLabelRepositoryListener listener;
        private int labelType = -1;

        public GetAllUnsentPrintLabelTask(int labelType, PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
            this.labelType = labelType;
        }

        public GetAllUnsentPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<PrintLabelBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            List<PrintLabelEntity> printLabelEntities;
            if (labelType != -1) {
                printLabelEntities = printLabelDao.getAllUnsentPrintLabel(labelType);
            } else {
                printLabelEntities = printLabelDao.getAllUnsentPrintLabel();
            }
            ArrayList<PrintLabelBean> printLabelList = new ArrayList<>();
            for (PrintLabelEntity phonePrintLabelEntity : printLabelEntities) {
                PrintLabelBean printLabelBean = phonePrintLabelEntity.getBean();
                printLabelList.add(printLabelBean);
            }
            return printLabelList;
        }

        @Override
        protected void onPostExecute(ArrayList<PrintLabelBean> result) {
            super.onPostExecute(result);
            if (result != null) {
                listener.onAllUnsentListLoaded(labelType, result);
            } else
                listener.onFailed();
        }
    }

    private static class GetAllSentPrintLabelTask extends AsyncTask<String, Integer, ArrayList<PrintLabelBean>> {
        private final PrintLabelRepositoryListener listener;
        private int labelType = -1;

        public GetAllSentPrintLabelTask(int labelType, PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
            this.labelType = labelType;
        }

        public GetAllSentPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<PrintLabelBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            List<PrintLabelEntity> printLabelEntities;
            if (labelType != -1) {
                printLabelEntities = printLabelDao.getAllSentPrintLabel(labelType);
            } else {
                printLabelEntities = printLabelDao.getAllSentPrintLabel();
            }
            ArrayList<PrintLabelBean> printLabelList = new ArrayList<>();
            for (PrintLabelEntity phonePrintLabelEntity : printLabelEntities) {
                PrintLabelBean printLabelBean = phonePrintLabelEntity.getBean();
                printLabelList.add(printLabelBean);
            }
            return printLabelList;
        }

        @Override
        protected void onPostExecute(ArrayList<PrintLabelBean> result) {
            super.onPostExecute(result);
            if (result != null) {
                listener.onAllSentListLoaded(labelType, result);
            } else
                listener.onFailed();
        }
    }

    private static class GetPrintLabelTask extends AsyncTask<String, Integer, PrintLabelBean> {
        private final String printLabelID;
        private final PrintLabelRepositoryListener listener;

        public GetPrintLabelTask(String printLabelID, PrintLabelRepositoryListener listener) {
            super();
            this.printLabelID = printLabelID;
            this.listener = listener;
        }

        @Override
        protected PrintLabelBean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            List<PrintLabelEntity> printLabelEntities = printLabelDao.getPrintLabel(printLabelID);
            if (printLabelEntities != null && !printLabelEntities.isEmpty()) {
                return printLabelEntities.get(0).getBean();
            } else {
                return null;
            }
        }

        @Override
        protected void onPostExecute(PrintLabelBean result) {
            super.onPostExecute(result);
            if (result != null)
                listener.onPrintLabelBeanLoaded(result);
            else
                listener.onFailed();
        }
    }

    private static class DeleteAllPrintLabelTask extends AsyncTask<String, Integer, Boolean> {
        private final PrintLabelRepositoryListener listener;

        public DeleteAllPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            printLabelDao.deleteAll();
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                listener.onDeleteAllCompleted();
            } else
                listener.onFailed();
        }
    }

    private static class DeleteAllUnsentPrintLabelTask extends AsyncTask<String, Integer, Boolean> {
        private final PrintLabelRepositoryListener listener;
        private int labelType = -1;

        public DeleteAllUnsentPrintLabelTask(int labelType, PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
            this.labelType = labelType;
        }

        public DeleteAllUnsentPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            if (labelType != -1) {
                printLabelDao.deleteAllUnsentPrintLabel(labelType);
            } else {
                printLabelDao.deleteAllUnsentPrintLabel();
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                listener.onDeleteAllUnsentCompleted(labelType);
            } else
                listener.onFailed();
        }
    }

    private static class DeleteAllSentPrintLabelTask extends AsyncTask<String, Integer, Boolean> {
        private final PrintLabelRepositoryListener listener;
        private int labelType = -1;
        private String key = "";

        public DeleteAllSentPrintLabelTask(String key, int labelType, PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
            this.labelType = labelType;
            this.key = key;
        }

        public DeleteAllSentPrintLabelTask(PrintLabelRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            PrintLabelDao printLabelDao = CarrefourRoomDatabase.getDatabase().printLabelDao();
            if (labelType != -1) {
                printLabelDao.deleteAllSentPrintLabel(key, labelType);
            } else {
                printLabelDao.deleteAllSentPrintLabel();
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                listener.onDeleteAllSentCompleted(key, labelType);
            } else
                listener.onFailed();
        }
    }


    public static interface PrintLabelRepositoryListener {


        void onAddCompleted(PrintLabelBean printLabelBean);

        void onAllListLoaded(ArrayList<PrintLabelBean> printLabelList);

        void onAllSentListLoaded(int labelType, ArrayList<PrintLabelBean> printLabelList);

        void onAllUnsentListLoaded(int labelType, ArrayList<PrintLabelBean> printLabelList);

        void onDeleteAllCompleted();

        void onDeleteAllSentCompleted(String key, int labelType);

        void onDeleteAllUnsentCompleted(int labelType);

        void onDeleteCompleted(PrintLabelBean printLabelBean);

        void onFailed();

        void onUpdateCompleted(PrintLabelBean printLabelBean);

        void onPrintLabelBeanLoaded(PrintLabelBean printLabelBean);

    }

}
