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.OutOfStockDao;
import in.techware.carrefour.dbUtils.entity.OutOfStockEntity;
import in.techware.carrefour.model.OutOfStockBean;

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

    private static OutOfStockRepository instance;


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

    public void insertOutOfStock(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
        InsertOutOfStockTask insertOutOfStockTask = new InsertOutOfStockTask(outOfStockBean, listener);
        insertOutOfStockTask.execute();

    }

    public void updateOutOfStock(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
        UpdateOutOfStockTask updateOutOfStockTask = new UpdateOutOfStockTask(outOfStockBean, listener);
        updateOutOfStockTask.execute();

    }

    public void deleteOutOfStock(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
        DeleteOutOfStockTask deleteOutOfStockTask = new DeleteOutOfStockTask(outOfStockBean, listener);
        deleteOutOfStockTask.execute();

    }

    public void getAllOutOfStocks(OutOfStockRepositoryListener listener) {
        GetAllOutOfStockTask getAllOutOfStockTask = new GetAllOutOfStockTask(listener);
        getAllOutOfStockTask.execute();

    }

    public void getAllUnsentOutOfStocks(OutOfStockRepositoryListener listener) {
        GetAllUnsentOutOfStockTask getAllUnsentOutOfStockTask = new GetAllUnsentOutOfStockTask(listener);
        getAllUnsentOutOfStockTask.execute();

    }

    public void getAllSentOutOfStocks(OutOfStockRepositoryListener listener) {
        GetAllSentOutOfStockTask getAllSentOutOfStockTask = new GetAllSentOutOfStockTask(listener);
        getAllSentOutOfStockTask.execute();

    }

    public void getOutOfStock(String outOfStockID, OutOfStockRepositoryListener listener) {
        GetOutOfStockTask getOutOfStockTask = new GetOutOfStockTask(outOfStockID, listener);
        getOutOfStockTask.execute();

    }

    public void deleteAllOutOfStocks(OutOfStockRepositoryListener listener) {
        DeleteAllOutOfStockTask deleteAllOutOfStockTask = new DeleteAllOutOfStockTask(listener);
        deleteAllOutOfStockTask.execute();

    }

    public void deleteAllUnsentOutOfStocks(OutOfStockRepositoryListener listener) {
        DeleteAllUnsentOutOfStockTask deleteAllUnsentOutOfStockTask = new DeleteAllUnsentOutOfStockTask(listener);
        deleteAllUnsentOutOfStockTask.execute();

    }

    public void deleteAllSentOutOfStocks(OutOfStockRepositoryListener listener) {
        DeleteAllSentOutOfStockTask deleteAllSentOutOfStockTask = new DeleteAllSentOutOfStockTask(listener);
        deleteAllSentOutOfStockTask.execute();

    }

    private static class InsertOutOfStockTask extends AsyncTask<String, Integer, Long> {
        private final OutOfStockBean outOfStockBean;
        private final OutOfStockRepositoryListener listener;

        public InsertOutOfStockTask(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
            super();
            this.outOfStockBean = outOfStockBean;
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(String... params) {
            //System.out.println(">>>>>>>>>doInBackground");
            OutOfStockEntity outOfStockEntity = new OutOfStockEntity(outOfStockBean);
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            long id = outOfStockDao.insert(outOfStockEntity);
            return id;
        }

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

    private static class UpdateOutOfStockTask extends AsyncTask<String, Integer, Boolean> {
        private final OutOfStockBean outOfStockBean;
        private final OutOfStockRepositoryListener listener;

        public UpdateOutOfStockTask(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
            super();
            this.outOfStockBean = outOfStockBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockEntity outOfStockEntity = new OutOfStockEntity(outOfStockBean);
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            outOfStockDao.update(outOfStockEntity);
            return true;
        }

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

    private static class DeleteOutOfStockTask extends AsyncTask<String, Integer, Boolean> {
        private final OutOfStockBean outOfStockBean;
        private final OutOfStockRepositoryListener listener;

        public DeleteOutOfStockTask(OutOfStockBean outOfStockBean, OutOfStockRepositoryListener listener) {
            super();
            this.outOfStockBean = outOfStockBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockEntity outOfStockEntity = new OutOfStockEntity(outOfStockBean);
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            outOfStockDao.delete(outOfStockEntity);
            return true;
        }

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

    private static class GetAllOutOfStockTask extends AsyncTask<String, Integer, ArrayList<OutOfStockBean>> {
        private final OutOfStockRepositoryListener listener;

        public GetAllOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<OutOfStockBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            List<OutOfStockEntity> outOfStockEntities = outOfStockDao.loadAllOutOfStocks();
            ArrayList<OutOfStockBean> outOfStockList = new ArrayList<>();
            for (OutOfStockEntity phoneOutOfStockEntity : outOfStockEntities) {
                OutOfStockBean outOfStockBean = phoneOutOfStockEntity.getBean();
                outOfStockList.add(outOfStockBean);
            }
            return outOfStockList;
        }

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

    private static class GetAllUnsentOutOfStockTask extends AsyncTask<String, Integer, ArrayList<OutOfStockBean>> {
        private final OutOfStockRepositoryListener listener;

        public GetAllUnsentOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<OutOfStockBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            List<OutOfStockEntity> outOfStockEntities = outOfStockDao.getAllUnsentOutOfStock();
            ArrayList<OutOfStockBean> outOfStockList = new ArrayList<>();
            for (OutOfStockEntity phoneOutOfStockEntity : outOfStockEntities) {
                OutOfStockBean outOfStockBean = phoneOutOfStockEntity.getBean();
                outOfStockList.add(outOfStockBean);
            }
            return outOfStockList;
        }

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

    private static class GetAllSentOutOfStockTask extends AsyncTask<String, Integer, ArrayList<OutOfStockBean>> {
        private final OutOfStockRepositoryListener listener;

        public GetAllSentOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<OutOfStockBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            List<OutOfStockEntity> outOfStockEntities = outOfStockDao.getAllSentOutOfStock();
            ArrayList<OutOfStockBean> outOfStockList = new ArrayList<>();
            for (OutOfStockEntity phoneOutOfStockEntity : outOfStockEntities) {
                OutOfStockBean outOfStockBean = phoneOutOfStockEntity.getBean();
                outOfStockList.add(outOfStockBean);
            }
            return outOfStockList;
        }

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

    private static class GetOutOfStockTask extends AsyncTask<String, Integer, OutOfStockBean> {
        private final String outOfStockID;
        private final OutOfStockRepositoryListener listener;

        public GetOutOfStockTask(String outOfStockID, OutOfStockRepositoryListener listener) {
            super();
            this.outOfStockID = outOfStockID;
            this.listener = listener;
        }

        @Override
        protected OutOfStockBean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            List<OutOfStockEntity> outOfStockEntities = outOfStockDao.getOutOfStock(outOfStockID);
            if (outOfStockEntities != null && !outOfStockEntities.isEmpty()) {
                return outOfStockEntities.get(0).getBean();
            } else {
                return null;
            }
        }

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

    private static class DeleteAllOutOfStockTask extends AsyncTask<String, Integer, Boolean> {
        private final OutOfStockRepositoryListener listener;

        public DeleteAllOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

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

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

    private static class DeleteAllUnsentOutOfStockTask extends AsyncTask<String, Integer, Boolean> {
        private final OutOfStockRepositoryListener listener;

        public DeleteAllUnsentOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            outOfStockDao.deleteAllUnsentOutOfStock();
            return true;
        }

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

    private static class DeleteAllSentOutOfStockTask extends AsyncTask<String, Integer, Boolean> {
        private final OutOfStockRepositoryListener listener;

        public DeleteAllSentOutOfStockTask(OutOfStockRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            OutOfStockDao outOfStockDao = CarrefourRoomDatabase.getDatabase().outOfStockDao();
            outOfStockDao.deleteAllSentOutOfStock();
            return true;
        }

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


    public static interface OutOfStockRepositoryListener {


        void onAddCompleted(OutOfStockBean outOfStockBean);

        void onAllListLoaded(ArrayList<OutOfStockBean> outOfStockList);

        void onAllSentListLoaded(ArrayList<OutOfStockBean> outOfStockList);

        void onAllUnsentListLoaded(ArrayList<OutOfStockBean> outOfStockList);

        void onDeleteAllCompleted();

        void onDeleteAllSentCompleted();

        void onDeleteAllUnsentCompleted();

        void onDeleteCompleted(OutOfStockBean outOfStockBean);

        void onFailed();

        void onUpdateCompleted(OutOfStockBean outOfStockBean);

        void onOutOfStockBeanLoaded(OutOfStockBean outOfStockBean);

    }

}
