import 'dart:async';
import 'dart:io';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

/// Данные о таблице сессии пользователя.
const String tableSession = "session";

const String columnMerchantID = "merchant_id"; // DIN code, который вводится при авторизации
const String columnToken = "token"; // Токен для pos. Приходит с бэкэнда.
const String columnPosID = "pos_id"; // идентификатор для создания токена на бэке.
const String columnDocID = "doc_id"; // идентификатор, для проведения покупки на бэкенде.

/// Данные о таблице данных приложения.
const String tableSettings = "settings";

const String columnCurrency = "currency"; // валюта.
const String columnLocale = "locale"; // локаль.

//{
//  columnMerchantID: merchantID,
//  columnToken: token,
//  columnPosID: posID,
//  columnDocID: docID
//}

/// База данных, для хранения временных данных (din, token, locale, etc.)
class SqliteHelper {

  Database db;

  Future open() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "demo.db");
    db = await openDatabase(path, version: 1,
        onCreate: (Database db, int version) async {

          await db.execute('''create table $tableSession ( 
                  $columnMerchantID text primary key,
                  $columnToken text, 
                  $columnPosID text,
                  $columnDocID integer)''');

          await db.execute('''create table $tableSettings ( 
                  $columnCurrency integer, 
                  $columnLocale text)''');
        });
  }

  /// Создается запись в таблице, содержащая
  /// необходимые для идентификации пользователя и проведения запросов.
  Future createSession(String merchantID, String posID, String token) async {

    Map session = {
      columnMerchantID: merchantID,
      columnPosID: posID,
      columnToken: token,
      columnDocID: 0
    };

    return db.insert(tableSession, session);
  }

  /// Создается запись в таблице, содержащая данные, которые не зависят от сессии.
  Future createAppInfo(int currency, String locale) async {
    List<Map> appInfo = await db.query(tableSettings);
    if (appInfo.length > 0) {
      return null;
    } else {
      return db.insert(tableSettings, {
        columnCurrency: currency,
        columnLocale: locale
      });
    }
  }

  Future<Map> getSettings(bool withSession) async {

    Map results = new Map();
    Map settings = await selectAll(tableSettings);

    if (settings != null && settings.isNotEmpty) {
      results.addAll(settings);
    }

    if (withSession) {
      Map session = await selectAll(tableSession);
      if (session != null && session.isNotEmpty) {
        results.addAll(session);
      }
    }

    return results;
  }

  Future<String> getToken() async {
    Map session = await selectAll(tableSession);
    String token = session != null ? session[columnToken] : null;
    return token;
  }

  Future<String> getMerchantID() async {
    Map session = await selectAll(tableSession);
    String merchantID = session != null ? session[columnMerchantID] : null;
    return merchantID;
  }

  Future<String> getPosID() async {
    Map session = await selectAll(tableSession);
    return session != null ? session[columnPosID] : new DateTime.now().millisecondsSinceEpoch.toString();
  }

  Future<int> getDocID() async {
    Map session = await selectAll(tableSession);
    int docID = session != null ? session[columnDocID] : 0;
    db.update(tableSession, {columnDocID: docID + 1});
    return docID;
  }

  Future<String> getLocale() async {
    Map settings = await selectAll(tableSettings);
    String locale = settings != null ? settings[columnLocale] : null;
    return locale;
  }

  Future saveLocale(String locale) async {
    db.update(tableSettings, {columnLocale: locale});
  }

  Future<int> getCurrency() async {
    Map settings = await selectAll(tableSettings);
    int currency = settings != null ? settings[columnCurrency] : null;
    return currency;
  }

  Future saveCurrency(int currency) async {
    db.update(tableSettings, {columnCurrency: currency});
  }

  Future<Map> selectAll(String table) async {

    List<Map> maps = await db.query(table, columns: null);

    if (maps.length > 0) {
      return maps.first;
    }

    return null;
  }

  Future clear() async {
    return await db.delete(tableSession, where: null);
  }
}
