import 'dart:async';

import 'package:floor/floor.dart';
import 'package:skillcourt/dao/club_dao.dart';
import 'package:skillcourt/dao/group_dao.dart';
import 'package:skillcourt/dao/player_dao.dart';
import 'package:skillcourt/entity/club.dart';
import 'package:skillcourt/entity/group.dart';
import 'package:skillcourt/entity/player.dart';
import 'package:sqflite/sqflite.dart' as sqflite;
import 'package:skillcourt/dao/game_score_dao.dart';
import 'package:skillcourt/entity/game_score.dart';
import 'package:skillcourt/game_session.dart';

part 'database.g.dart';

/// Convert [DateTime] to [String] and vice-versa.
class DateTimeConverter extends TypeConverter<DateTime, String> {
  @override
  DateTime decode(String databaseValue) {
    return DateTime.parse(databaseValue);
  }

  @override
  String encode(DateTime value) {
    return value.toIso8601String();
  }
}

/// Convert [DateTime?] to [String] and vice-versa.
class DateTimeNullConverter extends TypeConverter<DateTime?, String> {
  @override
  DateTime? decode(String databaseValue) {
    return DateTime.parse(databaseValue);
  }

  @override
  String encode(DateTime? value) {
    if (value == null) {
      return DateTime.now().toIso8601String();
    } else {
      return value.toIso8601String();
    }
  }
}

/// Convert [int?] to [int] and vice-versa.
class NullableIntConverter extends TypeConverter<int?, int> {
  @override
  int? decode(int databaseValue) {
    return databaseValue;
  }

  @override
  int encode(int? value) {
    if (value == null) {
      throw Exception('value cannot be null');
    } else {
      return value;
    }
  }
}

/// Service for accessing the underlying sqlite
/// [Database] for the application.
///
/// For migrations information, see: https://github.com/vitusortner/floor/blob/develop/docs/migrations.md
@TypeConverters(
    [DateTimeConverter, DateTimeNullConverter, NullableIntConverter])
@Database(version: 1, entities: [GameScore, Player, Club, Group])
abstract class DatabaseService extends FloorDatabase {
  GameScoreDao get gameScoreDao;
  PlayerDao get playerDao;
  ClubDao get clubDao;
  GroupDao get groupDao;
}
