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.WasteDao;
import in.techware.carrefour.dbUtils.entity.WasteEntity;
import in.techware.carrefour.model.WasteBean;

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

    private static WasteRepository instance;


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

    public void insertWaste(WasteBean wasteBean, WasteRepositoryListener listener) {
        InsertWasteTask insertWasteTask = new InsertWasteTask(wasteBean, listener);
        insertWasteTask.execute();

    }

    public void updateWaste(WasteBean wasteBean, WasteRepositoryListener listener) {
        UpdateWasteTask updateWasteTask = new UpdateWasteTask(wasteBean, listener);
        updateWasteTask.execute();

    }

    public void deleteWaste(WasteBean wasteBean, WasteRepositoryListener listener) {
        DeleteWasteTask deleteWasteTask = new DeleteWasteTask(wasteBean, listener);
        deleteWasteTask.execute();

    }

    public void getAllWastes(WasteRepositoryListener listener) {
        GetAllWasteTask getAllWasteTask = new GetAllWasteTask(listener);
        getAllWasteTask.execute();

    }

    public void getAllUnsentWastes(WasteRepositoryListener listener) {
        GetAllUnsentWasteTask getAllUnsentWasteTask = new GetAllUnsentWasteTask(listener);
        getAllUnsentWasteTask.execute();

    }

    public void getAllSentWastes(WasteRepositoryListener listener) {
        GetAllSentWasteTask getAllSentWasteTask = new GetAllSentWasteTask(listener);
        getAllSentWasteTask.execute();

    }

    public void getWaste(String wasteID, WasteRepositoryListener listener) {
        GetWasteTask getWasteTask = new GetWasteTask(wasteID, listener);
        getWasteTask.execute();

    }

    public void deleteAllWastes(WasteRepositoryListener listener) {
        DeleteAllWasteTask deleteAllWasteTask = new DeleteAllWasteTask(listener);
        deleteAllWasteTask.execute();

    }

    public void deleteAllUnsentWastes(WasteRepositoryListener listener) {
        DeleteAllUnsentWasteTask deleteAllUnsentWasteTask = new DeleteAllUnsentWasteTask(listener);
        deleteAllUnsentWasteTask.execute();

    }

    public void deleteAllSentWastes(WasteRepositoryListener listener) {
        DeleteAllSentWasteTask deleteAllSentWasteTask = new DeleteAllSentWasteTask(listener);
        deleteAllSentWasteTask.execute();

    }

    private static class InsertWasteTask extends AsyncTask<String, Integer, Long> {
        private final WasteBean wasteBean;
        private final WasteRepositoryListener listener;

        public InsertWasteTask(WasteBean wasteBean, WasteRepositoryListener listener) {
            super();
            this.wasteBean = wasteBean;
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(String... params) {
            //System.out.println(">>>>>>>>>doInBackground");
            WasteEntity wasteEntity = new WasteEntity(wasteBean);
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            long id = wasteDao.insert(wasteEntity);
            return id;
        }

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

    private static class UpdateWasteTask extends AsyncTask<String, Integer, Boolean> {
        private final WasteBean wasteBean;
        private final WasteRepositoryListener listener;

        public UpdateWasteTask(WasteBean wasteBean, WasteRepositoryListener listener) {
            super();
            this.wasteBean = wasteBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteEntity wasteEntity = new WasteEntity(wasteBean);
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            wasteDao.update(wasteEntity);
            return true;
        }

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

    private static class DeleteWasteTask extends AsyncTask<String, Integer, Boolean> {
        private final WasteBean wasteBean;
        private final WasteRepositoryListener listener;

        public DeleteWasteTask(WasteBean wasteBean, WasteRepositoryListener listener) {
            super();
            this.wasteBean = wasteBean;
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteEntity wasteEntity = new WasteEntity(wasteBean);
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            wasteDao.delete(wasteEntity);
            return true;
        }

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

    private static class GetAllWasteTask extends AsyncTask<String, Integer, ArrayList<WasteBean>> {
        private final WasteRepositoryListener listener;

        public GetAllWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<WasteBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            List<WasteEntity> wasteEntities = wasteDao.loadAllWastes();
            ArrayList<WasteBean> wasteList = new ArrayList<>();
            for (WasteEntity phoneWasteEntity : wasteEntities) {
                WasteBean wasteBean = phoneWasteEntity.getBean();
                wasteList.add(wasteBean);
            }
            return wasteList;
        }

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

    private static class GetAllUnsentWasteTask extends AsyncTask<String, Integer, ArrayList<WasteBean>> {
        private final WasteRepositoryListener listener;

        public GetAllUnsentWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<WasteBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            List<WasteEntity> wasteEntities = wasteDao.getAllUnsentWaste();
            ArrayList<WasteBean> wasteList = new ArrayList<>();
            for (WasteEntity phoneWasteEntity : wasteEntities) {
                WasteBean wasteBean = phoneWasteEntity.getBean();
                wasteList.add(wasteBean);
            }
            return wasteList;
        }

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

    private static class GetAllSentWasteTask extends AsyncTask<String, Integer, ArrayList<WasteBean>> {
        private final WasteRepositoryListener listener;

        public GetAllSentWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected ArrayList<WasteBean> doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            List<WasteEntity> wasteEntities = wasteDao.getAllSentWaste();
            ArrayList<WasteBean> wasteList = new ArrayList<>();
            for (WasteEntity phoneWasteEntity : wasteEntities) {
                WasteBean wasteBean = phoneWasteEntity.getBean();
                wasteList.add(wasteBean);
            }
            return wasteList;
        }

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

    private static class GetWasteTask extends AsyncTask<String, Integer, WasteBean> {
        private final String wasteID;
        private final WasteRepositoryListener listener;

        public GetWasteTask(String wasteID, WasteRepositoryListener listener) {
            super();
            this.wasteID = wasteID;
            this.listener = listener;
        }

        @Override
        protected WasteBean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            List<WasteEntity> wasteEntities = wasteDao.getWaste(wasteID);
            if (wasteEntities != null && !wasteEntities.isEmpty()) {
                return wasteEntities.get(0).getBean();
            } else {
                return null;
            }
        }

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

    private static class DeleteAllWasteTask extends AsyncTask<String, Integer, Boolean> {
        private final WasteRepositoryListener listener;

        public DeleteAllWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

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

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

    private static class DeleteAllUnsentWasteTask extends AsyncTask<String, Integer, Boolean> {
        private final WasteRepositoryListener listener;

        public DeleteAllUnsentWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            wasteDao.deleteAllUnsentWaste();
            return true;
        }

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

    private static class DeleteAllSentWasteTask extends AsyncTask<String, Integer, Boolean> {
        private final WasteRepositoryListener listener;

        public DeleteAllSentWasteTask(WasteRepositoryListener listener) {
            super();
            this.listener = listener;
        }

        @Override
        protected Boolean doInBackground(String... params) {
            System.out.println(">>>>>>>>>doInBackground");
            WasteDao wasteDao = CarrefourRoomDatabase.getDatabase().wasteDao();
            wasteDao.deleteAllSentWaste();
            return true;
        }

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


    public static interface WasteRepositoryListener {


        void onAddCompleted(WasteBean wasteBean);

        void onAllListLoaded(ArrayList<WasteBean> wasteList);

        void onAllSentListLoaded(ArrayList<WasteBean> wasteList);

        void onAllUnsentListLoaded(ArrayList<WasteBean> wasteList);

        void onDeleteAllCompleted();

        void onDeleteAllSentCompleted();

        void onDeleteAllUnsentCompleted();

        void onDeleteCompleted(WasteBean wasteBean);

        void onFailed();

        void onUpdateCompleted(WasteBean wasteBean);

        void onWasteBeanLoaded(WasteBean wasteBean);

    }

}
