import NetInfo, { NetInfoState } from '@react-native-community/netinfo';
import { StoreType, storage } from 'src/storage';
import { fetchLpi, fetchInHistory, fetchInMemoriam, updateMaster } from '@api/ranking';
import { initOfflineSetup, updateMapsCache } from './tilesService';
import { downloadFlags } from './flagsService';
import { fetchAndSaveAllTypesAndMasters } from './unMastersService';
import { fetchAndSaveStatistics } from './statisticsService';
import { saveTriumphsData } from './triumphsService';
import { saveSeriesRankingData } from './seriesRankingService';
import { updateDarePlacesDb, updateNmRegionsDb } from 'src/db';
import { cleanCache, deleteAvatarsDirectory } from './cacheService';
import { database } from 'src/watermelondb';
import { hasLocalBackup } from 'src/watermelondb/backup';
import { importChatsFromServer } from 'src/watermelondb/features/chat/data/importChatsFromServer';
import { backfillChatKeys, dedupeChats } from 'src/watermelondb/features/chat/data/chat.repo';

const lastUpdateNmRegions =
  (storage.get('lastUpdateNmRegions', StoreType.STRING) as string) || '1990-01-01';
const lastUpdateDarePlaces =
  (storage.get('lastUpdateDarePlaces', StoreType.STRING) as string) || '1990-01-01';

export const checkInternetConnection = async (): Promise<NetInfoState> => {
  const state = await NetInfo.fetch();
  return state;
};

export const syncDataWithServer = async (): Promise<void> => {
  const { isConnected } = await checkInternetConnection();

  if (isConnected) {
    await updateNmRegionsDb(lastUpdateNmRegions);
    await updateDarePlacesDb(lastUpdateDarePlaces);
    await initOfflineSetup();
    await updateMasterRanking();
    // await downloadFlags();
  }
};

export const invalidateMapCache = async () => {
  const { isConnected } = await checkInternetConnection();

  if (isConnected) {
    await updateMapsCache();
  }
};

export const setupDatabaseAndSync = async (): Promise<void> => {
  await syncDataWithServer();
  cleanCache();
  deleteAvatarsDirectory();
};

export const updateMasterRanking = async () => {
  const token = (storage.get('token', StoreType.STRING) as string) || '';
  await updateMaster();
  storage.remove('masterRanking');

  const dataLpi = await fetchLpi();

  if (dataLpi && dataLpi?.data) {
    storage.set('lpiRanking', JSON.stringify(dataLpi.data));
  }

  const dataInHistory = await fetchInHistory();

  if (dataInHistory && dataInHistory?.data) {
    storage.set('inHistoryRanking', JSON.stringify(dataInHistory.data));
  }

  const dataInMemoriam = await fetchInMemoriam();

  if (dataInMemoriam && dataInMemoriam?.data) {
    storage.set('inMemoriamRanking', JSON.stringify(dataInMemoriam.data));
  }

  await fetchAndSaveStatistics(token);
  await fetchAndSaveAllTypesAndMasters();
  await saveTriumphsData();
  await saveSeriesRankingData();
};

export async function initializeDatabase(token: string) {
  const chatsCount = await database.get('chats').query().fetchCount();
  if (chatsCount > 0) {
    const messagesCount = await database.get('messages').query().fetchCount();
    if (messagesCount === 0) {
      await importChatsFromServer(token);
      return;
    }

    await backfillChatKeys();
    await dedupeChats();
    console.log('Database already initialized');
    return;
  } else {
    console.log('Importing chats from server...');
    await importChatsFromServer(token);
  }

  // TO DO
  // const hasBackup = await hasLocalBackup();
}

export default setupDatabaseAndSync;
