import 'package:comunic/helpers/database/database_contract.dart';
import 'package:connectivity/connectivity.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

/// Database Helper
///
/// Manage the connection to the local SQLite database
///
/// @author Pierre HUBERT

abstract class DatabaseHelper {
  static Database _db;

  /// Open the database
  static Future<void> open() async {
    if (_db != null && _db.isOpen) return;

    var databasePath = await getDatabasesPath();
    _db = await openDatabase(
        join(databasePath, DatabaseContract.DATABASE_FILE_NAME),
        version: DatabaseContract.DATABASE_VERSION,
        onUpgrade: _performDatabaseUpdate,
        onCreate: _initializeDatabase);
  }

  /// Get a database instance
  static Future<Database> get() async {
    await open();
    return _db;
  }

  /// Cleanup database
  static Future<void> cleanUpDatabase() async {
    // If connected to a network, cleanup user information
    if (await Connectivity().checkConnectivity() != ConnectivityResult.none)
      await _db.execute("DELETE FROM ${UserTableContract.TABLE_NAME}");
  }

  /// Perform database update
  ///
  /// Currently : delete all the database tables and initialize it again
  static Future<void> _performDatabaseUpdate(
      Database db, int oldVersion, int newVersion) async {
    // Drop users table
    await db.execute("DROP TABLE IF EXISTS ${UserTableContract.TABLE_NAME}");

    // Drop conversations table
    await db.execute(
        "DROP TABLE IF EXISTS ${ConversationTableContract.TABLE_NAME}");

    // Drop conversations messages table
    await db.execute(
        "DROP TABLE IF EXISTS ${ConversationsMessagesTableContract.TABLE_NAME}");

    // Drop friends list table
    await db
        .execute("DROP TABLE IF EXISTS ${FriendsListTableContract.TABLE_NAME}");

    // Initialize database again
    await _initializeDatabase(db, newVersion);
  }

  /// Initialize the database
  static Future<void> _initializeDatabase(Database db, int version) async {
    // Create users table
    await db.execute("CREATE TABLE ${UserTableContract.TABLE_NAME} ("
        "${UserTableContract.C_ID} INTEGER PRIMARY KEY, "
        "${UserTableContract.C_FIRST_NAME} TEXT, "
        "${UserTableContract.C_LAST_NAME} TEXT, "
        "${UserTableContract.C_VISIBILITY} TEXT, "
        "${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT, "
        "${UserTableContract.C_ACCOUNT_IMAGE_URL} TEXT, "
        "${UserTableContract.C_CUSTOM_EMOJIES} TEXT"
        ")");

    // Create conversations table
    await db.execute("CREATE TABLE ${ConversationTableContract.TABLE_NAME} ("
        "${ConversationTableContract.C_ID} INTEGER PRIMARY KEY, "
        "${ConversationTableContract.C_OWNER_ID} INTEGER, "
        "${ConversationTableContract.C_LAST_ACTIVE} INTEGER, "
        "${ConversationTableContract.C_NAME} TEXT, "
        "${ConversationTableContract.C_FOLLOWING} INTEGER, "
        "${ConversationTableContract.C_SAW_LAST_MESSAGE} INTEGER, "
        "${ConversationTableContract.C_MEMBERS} TEXT, "
        "${ConversationTableContract.C_CAN_EVERYONE_ADD_MEMBERS} INTEGER"
        ")");

    // Create conversation messages table
    await db.execute(
        "CREATE TABLE ${ConversationsMessagesTableContract.TABLE_NAME} ("
        "${ConversationsMessagesTableContract.C_ID} INTEGER PRIMARY KEY, "
        "${ConversationsMessagesTableContract.C_CONVERSATION_ID} INTEGER, "
        "${ConversationsMessagesTableContract.C_USER_ID} INTEGER, "
        "${ConversationsMessagesTableContract.C_TIME_INSERT} INTEGER, "
        "${ConversationsMessagesTableContract.C_MESSAGE} TEXT, "
        "${ConversationsMessagesTableContract.C_IMAGE_URL} TEXT"
        ")");

    // Friends list table
    await db.execute("CREATE TABLE ${FriendsListTableContract.TABLE_NAME} ("
        "${FriendsListTableContract.C_ID} INTEGER PRIMARY KEY, "
        "${FriendsListTableContract.C_ACCEPTED} INTEGER, "
        "${FriendsListTableContract.C_LAST_ACTIVE} INTEGER, "
        "${FriendsListTableContract.C_FOLLOWING} INTEGER, "
        "${FriendsListTableContract.C_CAN_POST_TEXTS} INTEGER"
        ")");
  }
}