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.FacingDao;
import in.techware.carrefour.dbUtils.entity.FacingEntity;
import in.techware.carrefour.model.FacingBean;

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

    private static FacingRepository instance;


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

    public void insertFacing(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.InsertFacingTask insertFacingTask = new FacingRepository.InsertFacingTask(facingBean, listener);
        insertFacingTask.execute();

    }

    public void updateFacing(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.UpdateFacingTask updateFacingTask = new FacingRepository.UpdateFacingTask(facingBean, listener);
        updateFacingTask.execute();

    }

    public void deleteFacing(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.DeleteFacingTask deleteFacingTask = new FacingRepository.DeleteFacingTask(facingBean, listener);
        deleteFacingTask.execute();

    }

    public void getAllFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.GetAllFacingTask getAllFacingTask = new FacingRepository.GetAllFacingTask(listener);
        getAllFacingTask.execute();

    }

    public void getAllUnsentFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.GetAllUnsentFacingTask getAllUnsentFacingTask = new FacingRepository.GetAllUnsentFacingTask(listener);
        getAllUnsentFacingTask.execute();

    }

    public void getAllSentFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.GetAllSentFacingTask getAllSentFacingTask = new FacingRepository.GetAllSentFacingTask(listener);
        getAllSentFacingTask.execute();

    }

    public void getFacing(String facingID, FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.GetFacingTask getFacingTask = new FacingRepository.GetFacingTask(facingID, listener);
        getFacingTask.execute();

    }

    public void deleteAllFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.DeleteAllFacingTask deleteAllFacingTask = new FacingRepository.DeleteAllFacingTask(listener);
        deleteAllFacingTask.execute();

    }

    public void deleteAllUnsentFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.DeleteAllUnsentFacingTask deleteAllUnsentFacingTask = new FacingRepository.DeleteAllUnsentFacingTask(listener);
        deleteAllUnsentFacingTask.execute();

    }

    public void deleteAllSentFacings(FacingRepository.FacingRepositoryListener listener) {
        FacingRepository.DeleteAllSentFacingTask deleteAllSentFacingTask = new FacingRepository.DeleteAllSentFacingTask(listener);
        deleteAllSentFacingTask.execute();

    }

    private static class InsertFacingTask extends AsyncTask<String, Integer, Long> {
        private final FacingBean facingBean;
        private final FacingRepository.FacingRepositoryListener listener;

        public InsertFacingTask(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
            super();
            this.facingBean = facingBean;
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(String... params) {
            //System.out.println(">>>>>>>>>doInBackground");
            FacingEntity facingEntity = new FacingEntity(facingBean);
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            long id = facingDao.insert(facingEntity);
            return id;
        }

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

    private static class UpdateFacingTask extends AsyncTask<String, Integer, Boolean> {
        private final FacingBean facingBean;
        private final FacingRepository.FacingRepositoryListener listener;

        public UpdateFacingTask(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
            super();
            this.facingBean = facingBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingEntity facingEntity = new FacingEntity(facingBean);
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            facingDao.update(facingEntity);
            return true;
        }

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

    private static class DeleteFacingTask extends AsyncTask<String, Integer, Boolean> {
        private final FacingBean facingBean;
        private final FacingRepository.FacingRepositoryListener listener;

        public DeleteFacingTask(FacingBean facingBean, FacingRepository.FacingRepositoryListener listener) {
            super();
            this.facingBean = facingBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingEntity facingEntity = new FacingEntity(facingBean);
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            facingDao.delete(facingEntity);
            return true;
        }

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

    private static class GetAllFacingTask extends AsyncTask<String, Integer, ArrayList<FacingBean>> {
        private final FacingRepository.FacingRepositoryListener listener;

        public GetAllFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<FacingBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            List<FacingEntity> facingEntities = facingDao.loadAllFacings();
            ArrayList<FacingBean> facingList = new ArrayList<>();
            for (FacingEntity phoneFacingEntity : facingEntities) {
                FacingBean facingBean = phoneFacingEntity.getBean();
                facingList.add(facingBean);
            }
            return facingList;
        }

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

    private static class GetAllUnsentFacingTask extends AsyncTask<String, Integer, ArrayList<FacingBean>> {
        private final FacingRepository.FacingRepositoryListener listener;

        public GetAllUnsentFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<FacingBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            List<FacingEntity> facingEntities = facingDao.getAllUnsentFacing();
            ArrayList<FacingBean> facingList = new ArrayList<>();
            for (FacingEntity phoneFacingEntity : facingEntities) {
                FacingBean facingBean = phoneFacingEntity.getBean();
                facingList.add(facingBean);
            }
            return facingList;
        }

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

    private static class GetAllSentFacingTask extends AsyncTask<String, Integer, ArrayList<FacingBean>> {
        private final FacingRepository.FacingRepositoryListener listener;

        public GetAllSentFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<FacingBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            List<FacingEntity> facingEntities = facingDao.getAllSentFacing();
            ArrayList<FacingBean> facingList = new ArrayList<>();
            for (FacingEntity phoneFacingEntity : facingEntities) {
                FacingBean facingBean = phoneFacingEntity.getBean();
                facingList.add(facingBean);
            }
            return facingList;
        }

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

    private static class GetFacingTask extends AsyncTask<String, Integer, FacingBean> {
        private final String facingID;
        private final FacingRepository.FacingRepositoryListener listener;

        public GetFacingTask(String facingID, FacingRepository.FacingRepositoryListener listener) {
            super();
            this.facingID = facingID;
            this.listener = listener;
        }

        @Override
        protected FacingBean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            List<FacingEntity> facingEntities = facingDao.getFacing(facingID);
            if (facingEntities != null && !facingEntities.isEmpty()) {
                return facingEntities.get(0).getBean();
            } else {
                return null;
            }
        }

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

    private static class DeleteAllFacingTask extends AsyncTask<String, Integer, Boolean> {
        private final FacingRepository.FacingRepositoryListener listener;

        public DeleteAllFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

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

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

    private static class DeleteAllUnsentFacingTask extends AsyncTask<String, Integer, Boolean> {
        private final FacingRepository.FacingRepositoryListener listener;

        public DeleteAllUnsentFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            facingDao.deleteAllUnsentFacing();
            return true;
        }

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

    private static class DeleteAllSentFacingTask extends AsyncTask<String, Integer, Boolean> {
        private final FacingRepository.FacingRepositoryListener listener;

        public DeleteAllSentFacingTask(FacingRepository.FacingRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            FacingDao facingDao = CarrefourRoomDatabase.getDatabase().facingDao();
            facingDao.deleteAllSentFacing();
            return true;
        }

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


    public static interface FacingRepositoryListener {


        void onAddCompleted(FacingBean facingBean);

        void onAllListLoaded(ArrayList<FacingBean> facingList);

        void onAllSentListLoaded(ArrayList<FacingBean> facingList);

        void onAllUnsentListLoaded(ArrayList<FacingBean> facingList);

        void onDeleteAllCompleted();

        void onDeleteAllSentCompleted();

        void onDeleteAllUnsentCompleted();

        void onDeleteCompleted(FacingBean facingBean);

        void onFailed();

        void onUpdateCompleted(FacingBean facingBean);

        void onFacingBeanLoaded(FacingBean facingBean);

    }

}
