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.StockTakeDao;
import in.techware.carrefour.dbUtils.entity.StockTakeEntity;
import in.techware.carrefour.model.StockTakeBean;

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

    private static StockTakeRepository instance;


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

    public void insertStockTake(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
        InsertStockTakeTask insertStockTakeTask = new InsertStockTakeTask(stockTakeBean, listener);
        insertStockTakeTask.execute();

    }

    public void updateStockTake(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
        UpdateStockTakeTask updateStockTakeTask = new UpdateStockTakeTask(stockTakeBean, listener);
        updateStockTakeTask.execute();

    }

    public void deleteStockTake(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
        DeleteStockTakeTask deleteStockTakeTask = new DeleteStockTakeTask(stockTakeBean, listener);
        deleteStockTakeTask.execute();

    }

    public void getAllStockTakes(StockTakeRepositoryListener listener) {
        GetAllStockTakeTask getAllStockTakeTask = new GetAllStockTakeTask(listener);
        getAllStockTakeTask.execute();

    }

    public void getAllUnsentStockTakes(StockTakeRepositoryListener listener) {
        GetAllUnsentStockTakeTask getAllUnsentStockTakeTask = new GetAllUnsentStockTakeTask(listener);
        getAllUnsentStockTakeTask.execute();

    }

    public void getAllSentStockTakes(StockTakeRepositoryListener listener) {
        GetAllSentStockTakeTask getAllSentStockTakeTask = new GetAllSentStockTakeTask(listener);
        getAllSentStockTakeTask.execute();

    }

    public void getStockTake(String stockTakeID, StockTakeRepositoryListener listener) {
        GetStockTakeTask getStockTakeTask = new GetStockTakeTask(stockTakeID, listener);
        getStockTakeTask.execute();

    }

    public void deleteAllStockTakes(StockTakeRepositoryListener listener) {
        DeleteAllStockTakeTask deleteAllStockTakeTask = new DeleteAllStockTakeTask(listener);
        deleteAllStockTakeTask.execute();

    }

    public void deleteAllUnsentStockTakes(StockTakeRepositoryListener listener) {
        DeleteAllUnsentStockTakeTask deleteAllUnsentStockTakeTask = new DeleteAllUnsentStockTakeTask(listener);
        deleteAllUnsentStockTakeTask.execute();

    }

    public void deleteAllSentStockTakes(StockTakeRepositoryListener listener) {
        DeleteAllSentStockTakeTask deleteAllSentStockTakeTask = new DeleteAllSentStockTakeTask(listener);
        deleteAllSentStockTakeTask.execute();

    }

    private static class InsertStockTakeTask extends AsyncTask<String, Integer, Long> {
        private final StockTakeBean stockTakeBean;
        private final StockTakeRepositoryListener listener;

        public InsertStockTakeTask(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
            super();
            this.stockTakeBean = stockTakeBean;
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(String... params) {
            //System.out.println(">>>>>>>>>doInBackground");
            StockTakeEntity stockTakeEntity = new StockTakeEntity(stockTakeBean);
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            long id = stockTakeDao.insert(stockTakeEntity);
            return id;
        }

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

    private static class UpdateStockTakeTask extends AsyncTask<String, Integer, Boolean> {
        private final StockTakeBean stockTakeBean;
        private final StockTakeRepositoryListener listener;

        public UpdateStockTakeTask(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
            super();
            this.stockTakeBean = stockTakeBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeEntity stockTakeEntity = new StockTakeEntity(stockTakeBean);
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            stockTakeDao.update(stockTakeEntity);
            return true;
        }

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

    private static class DeleteStockTakeTask extends AsyncTask<String, Integer, Boolean> {
        private final StockTakeBean stockTakeBean;
        private final StockTakeRepositoryListener listener;

        public DeleteStockTakeTask(StockTakeBean stockTakeBean, StockTakeRepositoryListener listener) {
            super();
            this.stockTakeBean = stockTakeBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeEntity stockTakeEntity = new StockTakeEntity(stockTakeBean);
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            stockTakeDao.delete(stockTakeEntity);
            return true;
        }

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

    private static class GetAllStockTakeTask extends AsyncTask<String, Integer, ArrayList<StockTakeBean>> {
        private final StockTakeRepositoryListener listener;

        public GetAllStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<StockTakeBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            List<StockTakeEntity> stockTakeEntities = stockTakeDao.loadAllStockTakes();
            ArrayList<StockTakeBean> stockTakeList = new ArrayList<>();
            for (StockTakeEntity phoneStockTakeEntity : stockTakeEntities) {
                StockTakeBean stockTakeBean = phoneStockTakeEntity.getBean();
                stockTakeList.add(stockTakeBean);
            }
            return stockTakeList;
        }

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

    private static class GetAllUnsentStockTakeTask extends AsyncTask<String, Integer, ArrayList<StockTakeBean>> {
        private final StockTakeRepositoryListener listener;

        public GetAllUnsentStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<StockTakeBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            List<StockTakeEntity> stockTakeEntities = stockTakeDao.getAllUnsentStockTake();
            ArrayList<StockTakeBean> stockTakeList = new ArrayList<>();
            for (StockTakeEntity phoneStockTakeEntity : stockTakeEntities) {
                StockTakeBean stockTakeBean = phoneStockTakeEntity.getBean();
                stockTakeList.add(stockTakeBean);
            }
            return stockTakeList;
        }

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

    private static class GetAllSentStockTakeTask extends AsyncTask<String, Integer, ArrayList<StockTakeBean>> {
        private final StockTakeRepositoryListener listener;

        public GetAllSentStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<StockTakeBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            List<StockTakeEntity> stockTakeEntities = stockTakeDao.getAllSentStockTake();
            ArrayList<StockTakeBean> stockTakeList = new ArrayList<>();
            for (StockTakeEntity phoneStockTakeEntity : stockTakeEntities) {
                StockTakeBean stockTakeBean = phoneStockTakeEntity.getBean();
                stockTakeList.add(stockTakeBean);
            }
            return stockTakeList;
        }

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

    private static class GetStockTakeTask extends AsyncTask<String, Integer, StockTakeBean> {
        private final String stockTakeID;
        private final StockTakeRepositoryListener listener;

        public GetStockTakeTask(String stockTakeID, StockTakeRepositoryListener listener) {
            super();
            this.stockTakeID = stockTakeID;
            this.listener = listener;
        }

        @Override
        protected StockTakeBean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            List<StockTakeEntity> stockTakeEntities = stockTakeDao.getStockTake(stockTakeID);
            if (stockTakeEntities != null && !stockTakeEntities.isEmpty()) {
                return stockTakeEntities.get(0).getBean();
            } else {
                return null;
            }
        }

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

    private static class DeleteAllStockTakeTask extends AsyncTask<String, Integer, Boolean> {
        private final StockTakeRepositoryListener listener;

        public DeleteAllStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

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

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

    private static class DeleteAllUnsentStockTakeTask extends AsyncTask<String, Integer, Boolean> {
        private final StockTakeRepositoryListener listener;

        public DeleteAllUnsentStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            stockTakeDao.deleteAllUnsentStockTake();
            return true;
        }

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

    private static class DeleteAllSentStockTakeTask extends AsyncTask<String, Integer, Boolean> {
        private final StockTakeRepositoryListener listener;

        public DeleteAllSentStockTakeTask(StockTakeRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            StockTakeDao stockTakeDao = CarrefourRoomDatabase.getDatabase().stockTakeDao();
            stockTakeDao.deleteAllSentStockTake();
            return true;
        }

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


    public static interface StockTakeRepositoryListener {


        void onAddCompleted(StockTakeBean stockTakeBean);

        void onAllListLoaded(ArrayList<StockTakeBean> stockTakeList);

        void onAllSentListLoaded(ArrayList<StockTakeBean> stockTakeList);

        void onAllUnsentListLoaded(ArrayList<StockTakeBean> stockTakeList);

        void onDeleteAllCompleted();

        void onDeleteAllSentCompleted();

        void onDeleteAllUnsentCompleted();

        void onDeleteCompleted(StockTakeBean stockTakeBean);

        void onFailed();

        void onUpdateCompleted(StockTakeBean stockTakeBean);

        void onStockTakeBeanLoaded(StockTakeBean stockTakeBean);

    }

}
