package cgmblelib.database.dao;


import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

import cgmblelib.database.entity.PocGlucose;


/**
 * Created by minyuchun on 2019/1/11.
 * operation about database glucose
 */
@Dao
public interface DaoGlucose {
    /**
     * 新增数据
     *
     * @param glucose 数据
     * @return 返回插入的id
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long insert(PocGlucose glucose);

    /**
     * 新增多个数据
     *
     * @param glucoses 数据组
     * @return 返回插入的id组
     */
    @Insert
    long[] insertAll(PocGlucose... glucoses);

    /**
     * 删除数据
     *
     * @param glucose 数据
     * @return 返回删除的数据数量
     */
    @Delete
    int delete(PocGlucose glucose);

    //    @Delete
    @Query("DELETE FROM glucose where deviceId = :deviceId and glucoseId > :glucoseId")
    void removeAll(long deviceId, int glucoseId);

    /**
     * 跟新数据
     *
     * @param glucose 数据组
     */
    @Update(onConflict = OnConflictStrategy.REPLACE)
    int update(PocGlucose... glucose);

    /**
     * 跟新数据
     *
     * @param glucose 数据
     * @return 跟新的数据量
     */
    @Update(onConflict = OnConflictStrategy.REPLACE)
    int update(PocGlucose glucose);

    /**
     * 根据设备Id与设局ID获取指定的数据
     *
     * @param deviceId  设备ID
     * @param glucoseId 数据ID
     * @return 返回数据信息
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and glucoseId = :glucoseId")
    PocGlucose getGlucoseById(long deviceId, int glucoseId);//通过deviceId与glucoseId定位

    @Query("SELECT * FROM glucose where deviceId = :deviceId and abs(:timeMillis - timeInMillis) <= 90000")
    PocGlucose getGlucoseByTimeIoThread(long deviceId, long timeMillis);

    /**
     * 根据设备ID获取最新的血糖数据信息
     *
     * @param deviceId 设备ID
     * @return 返回数据信息
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and glucoseId = (SELECT MAX(glucoseId) FROM glucose where deviceId = :deviceId)")
    PocGlucose getLatestGlucose(long deviceId);//获取正常的经过计算的血糖数据

    /**
     * 根据设备ID获取最大的血糖数据ID
     *
     * @param deviceId 设备ID
     * @return 最大的血糖数据ID
     */
    @Query("SELECT MAX(glucoseId) FROM glucose where deviceId = :deviceId")
    int getMaxGlucoseId(long deviceId);

    /**
     * 获取该设备ID的血糖数据总数
     *
     * @param deviceId 设备ID
     * @return 血糖数据数量
     */
    @Query("SELECT COUNT(*) FROM glucose where deviceId = :deviceId")
    int getCountGlucose(long deviceId);

    /**
     * 根据设备ID获取最新血糖数据 -- 持久化 -- 升序
     *
     * @param deviceId 设备ID
     * @return 返回
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and glucoseId = (SELECT MAX(glucoseId) FROM glucose where deviceId = :deviceId)")
    LiveData<PocGlucose> getLatestGlucoseByDeviceId(long deviceId);


    /**
     * 根据设备ID获取所有的数据信息 升序 -- 持久化
     *
     * @param deviceId 设备ID
     * @return 返回持久化数据组
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId order by glucoseId asc")
    LiveData<List<PocGlucose>> getAllLiveDataGlucosesByDeviceId(long deviceId);


    /**
     * 根据设备ID获取所有的数据信息 升序
     *
     * @param deviceId 设备ID
     * @return 返回持久化数据组
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId order by glucoseId asc")
    List<PocGlucose> getAllGlucosesByDeviceId(long deviceId);

    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId order by glucoseId desc")
    List<PocGlucose> getAllGlucosesByDeviceIdDesc(long deviceId);

    /**
     * 获取所有有血糖值的有效数据
     *
     * @param deviceId 设备ID
     * @return 所有有血糖值的有效数据
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId and BGICount > 0 and errorCode == 0 order by glucoseId asc")
    List<PocGlucose> getAllEffectiveGlucosesByDeviceId(long deviceId);


    /**
     * 获取所有有血糖值的有效数据
     *
     * @param deviceId 设备ID
     * @return 所有有血糖值的有效数据
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId and glucoseId >= :startId and glucoseId <= :endId and BGICount > 0 and showGlucose > 1 order by glucoseId asc")
    List<PocGlucose> getGlucoseBetweenTime(long deviceId, int startId, int endId);


    /**
     * 获取所有有血糖值的有效数据
     *
     * @param deviceId 设备ID
     * @return 所有有血糖值的有效数据
     */
    @Query("SELECT Min(glucoseId) FROM glucose WHERE deviceId = :deviceId and year = :startYear and month = :startMonth and day= :startDay and hour= :startHour ")
    int getStartIdBetweenTime(long deviceId, int startYear, int startMonth, int startDay, int startHour);

    /**
     * 获取所有有血糖值的有效数据
     *
     * @param deviceId 设备ID
     * @return 所有有血糖值的有效数据
     */
    @Query("SELECT Max(glucoseId) FROM glucose WHERE deviceId = :deviceId and year = :endYear and month = :endMonth and day= :endDay and hour= :endHour")
    int getEndIdBetweenTime(long deviceId, int endYear, int endMonth, int endDay, int endHour);


    /**
     * 获取所有预热结束的点的数量
     *
     * @param deviceId 设备ID
     * @return 返回所有预热结束的点
     */
    @Query("SELECT COUNT(*) FROM glucose WHERE deviceId = :deviceId and BGICount > 0")
    int getCountPreheatEndByDeviceIdIoThread(long deviceId);

    /**
     * 查询分页数据
     *
     * @param deviceId 设备ID
     * @param limit    数据总数
     * @param offset   忽略的数据
     * @return 分页数据
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId and BGICount > 0 order by glucoseId DESC limit :limit offset :offset")
    List<PocGlucose> getPageData(long deviceId, int limit, int offset);

    /**
     * 获取最新的限制数据量,获取给定数量的最新的血糖数据
     *
     * @param deviceId 设备ID
     * @param limit    数据总数
     * @return 分页数据
     */
    @Query("SELECT * FROM glucose WHERE deviceId = :deviceId and BGICount > 0 order by glucoseId DESC limit :limit")
    List<PocGlucose> getLatestPageData(long deviceId, int limit);

    /**
     * 获取所有工作电流
     *
     * @param deviceId 发射器Id
     * @return 所有的工作电流
     */
    @Query("SELECT Iw FROM glucose where deviceId = :deviceId")
    float[] getIws(long deviceId);

    /**
     * 获取所有的空白电流
     *
     * @param deviceId 发射器Id
     * @return 所有的空白电流
     */
    @Query("SELECT Ib FROM glucose where deviceId = :deviceId")
    float[] getIbs(long deviceId);

    /**
     * 获取所有的温度
     *
     * @param deviceId 发射器Id
     * @return 所有的温度
     */
    @Query("SELECT T FROM glucose where deviceId = :deviceId")
    float[] getTs(long deviceId);

    /**
     * 获取所有校准点对应的glucoseId
     *
     * @param deviceId 发射器Id
     * @return 所有校准点
     */
    @Query("SELECT glucoseId FROM glucose where deviceId = :deviceId and BGICount = 1 and BGCount > 0")
    int[] getNewBgToGlucoseIds(long deviceId);

    /**
     * 获取所有校准点对应的校准值
     *
     * @param deviceId 发射器Id
     * @return 所有校准值
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and BGICount = 1 and BGCount > 0")
    List<PocGlucose> getNewBgValue(long deviceId);

    /**
     * 获取数据经历的年份
     *
     * @param deviceId 发射器Id
     * @return 所有的年
     */
    @Query("SELECT year FROM glucose where deviceId = :deviceId group by year order by year asc")
    int[] getYears(long deviceId);

    /**
     * 获取数据中的本年的所有月
     *
     * @param deviceId 发射器Id
     * @param year     年
     * @return 获取本年内经历的月
     */
    @Query("SELECT month FROM glucose where deviceId = :deviceId and year = :year group by month order by month asc")
    int[] getMonths(long deviceId, int year);

    /**
     * 获取该条数据中数据经历的本年当月的所有天
     *
     * @param deviceId 发射器Id
     * @param year     年
     * @param month    月
     * @return 获取本年本月内经历的天
     */
    @Query("SELECT day FROM glucose where deviceId = :deviceId and year = :year and month = :month group by day order by day asc")
    int[] getDays(long deviceId, int year, int month);

    /**
     * 获取当天中的所有数据
     *
     * @param deviceId 发射器Id
     * @param year     年
     * @param month    月
     * @param day      获取本年本月内经历的天
     * @return 获取每天的所有数据
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and year = :year and month = :month and day = :day and BGICount > 0 and showGlucose > 1 order by glucoseId asc")
    List<PocGlucose> getEveryDays(long deviceId, int year, int month, int day);

    /**
     * 获取当天所有校准点对应的校准值
     *
     * @param deviceId 发射器Id
     * @return 所有校准值
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and BGICount = 1 and BGCount > 0  and year = :year and month = :month and day = :day order by glucoseId asc")
    List<PocGlucose> getNewBgValueInDay(long deviceId, int year, int month, int day);

    /**
     * 获取当天中的所有数据
     *
     * @param deviceId 发射器Id
     * @param year     年
     * @param month    月
     * @param day      获取本年本月内经历的天
     * @return 获取每天的所有数据
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and year = :year and month = :month and day = :day and hour >= :startHour and BGICount > 0 and showGlucose > 1 order by glucoseId asc")
    List<PocGlucose> getStartDayGlucose(long deviceId, int year, int month, int day, int startHour);


    /**
     * 获取当天中的所有数据
     *
     * @param deviceId 发射器Id
     * @param year     年
     * @param month    月
     * @param day      获取本年本月内经历的天
     * @return 获取每天的所有数据
     */
    @Query("SELECT * FROM glucose where deviceId = :deviceId and year = :year and month = :month and day = :day and hour <= :endHour and BGICount > 0 and showGlucose > 1 order by glucoseId asc")
    List<PocGlucose> getEndDayGlucose(long deviceId, int year, int month, int day, int endHour);


    @Query("SELECT glucoseId FROM glucose where deviceId = :deviceId and errorCode == 7 order by glucoseId asc")
    int[] getContinuousAnomalyCurrentInitCheckGlucoseIdsIoThread(long deviceId);

    @Query("SELECT * From glucose where name = :name group by day order by year,month,day asc")
    List<PocGlucose> getGlucoseDayByName(String name);

    /**
     * 获取所有工作电流
     *
     * @param deviceId 发射器Id
     * @return 所有的工作电流
     */
    @Query("SELECT errorCode FROM glucose where deviceId = :deviceId")
    int[] getErrors(long deviceId);

    @Query("SELECT * FROM glucose where deviceId = :deviceId and timeInMillis > :timeMillisStart")
    List<PocGlucose> getGlucoseByDeviceIdAndTimeMillis(long deviceId, long timeMillisStart);

    @Query("SELECT * FROM glucose where timeInMillis BETWEEN :startTime AND :endTime")
    List<PocGlucose> getGlucoseByTimeMillis(long startTime, long endTime);

    @Query("DELETE FROM glucose")
    void clearGlucoseTable();
}
