/// Drift schema for the scheduler's local SQLite database.
///
/// This package owns SQLite and Drift details. The scheduler core continues to
/// depend only on domain objects and repository contracts.
library;

import 'package:drift/drift.dart';

part 'scheduler_db.g.dart';

/// Authoritative task rows.
@DataClassName('TaskRow')
class Tasks extends Table {
  TextColumn get id => text()();
  TextColumn get ownerId => text().named('owner_id')();
  TextColumn get title => text()();
  TextColumn get projectId => text().named('project_id')();
  TextColumn get parentId => text().named('parent_id').nullable()();
  TextColumn get type => text()();
  TextColumn get status => text()();
  TextColumn get priority => text().nullable()();
  TextColumn get reward => text()();
  TextColumn get difficulty => text()();
  IntColumn get durationMinutes =>
      integer().named('duration_minutes').nullable()();
  DateTimeColumn get scheduledStartUtc =>
      dateTime().named('scheduled_start_utc').nullable()();
  DateTimeColumn get scheduledEndUtc =>
      dateTime().named('scheduled_end_utc').nullable()();
  DateTimeColumn get actualStartUtc =>
      dateTime().named('actual_start_utc').nullable()();
  DateTimeColumn get actualEndUtc =>
      dateTime().named('actual_end_utc').nullable()();
  DateTimeColumn get completedAtUtc =>
      dateTime().named('completed_at_utc').nullable()();
  TextColumn get backlogTagsJson => text().named('backlog_tags_json')();
  TextColumn get reminderOverride =>
      text().named('reminder_override').nullable()();
  TextColumn get statsJson => text().named('stats_json')();
  DateTimeColumn get backlogEnteredAtUtc =>
      dateTime().named('backlog_entered_at_utc').nullable()();
  TextColumn get backlogEnteredProvenance =>
      text().named('backlog_entered_provenance').nullable()();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {id};
}

/// Project configuration rows.
@DataClassName('ProjectRow')
class Projects extends Table {
  TextColumn get id => text()();
  TextColumn get ownerId => text().named('owner_id')();
  TextColumn get name => text()();
  TextColumn get colorKey => text().named('color_key')();
  TextColumn get defaultPriority => text().named('default_priority')();
  TextColumn get defaultReward => text().named('default_reward')();
  TextColumn get defaultDifficulty => text().named('default_difficulty')();
  TextColumn get defaultReminderProfile =>
      text().named('default_reminder_profile')();
  IntColumn get defaultDurationMinutes =>
      integer().named('default_duration_minutes').nullable()();
  DateTimeColumn get archivedAtUtc =>
      dateTime().named('archived_at_utc').nullable()();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {id};
}

/// Recurring and one-off locked-time rows.
@DataClassName('LockedBlockRow')
class LockedBlocks extends Table {
  TextColumn get id => text()();
  TextColumn get ownerId => text().named('owner_id')();
  TextColumn get name => text()();
  TextColumn get date => text().nullable()();
  TextColumn get startTime => text().named('start_time')();
  TextColumn get endTime => text().named('end_time')();
  TextColumn get recurrenceJson => text().named('recurrence_json').nullable()();
  BoolColumn get hiddenByDefault => boolean().named('hidden_by_default')();
  TextColumn get projectId => text().named('project_id').nullable()();
  DateTimeColumn get archivedAtUtc =>
      dateTime().named('archived_at_utc').nullable()();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {id};
}

/// Date-scoped overrides for recurring locked blocks.
@DataClassName('LockedOverrideRow')
class LockedOverrides extends Table {
  TextColumn get id => text()();
  TextColumn get ownerId => text().named('owner_id')();
  TextColumn get lockedBlockId => text().named('locked_block_id').nullable()();
  TextColumn get date => text()();
  TextColumn get type => text()();
  TextColumn get name => text().nullable()();
  TextColumn get startTime => text().named('start_time').nullable()();
  TextColumn get endTime => text().named('end_time').nullable()();
  BoolColumn get hiddenByDefault => boolean().named('hidden_by_default')();
  TextColumn get projectId => text().named('project_id').nullable()();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {id};
}

/// Owner-level settings rows.
@DataClassName('SettingsRow')
class SettingsTable extends Table {
  @override
  String get tableName => 'settings';

  TextColumn get ownerId => text().named('owner_id')();
  TextColumn get timeZoneId => text().named('timezone_id')();
  IntColumn get dayStartMinutes => integer().named('day_start_minutes')();
  IntColumn get dayEndMinutes => integer().named('day_end_minutes')();
  BoolColumn get compactMode => boolean().named('compact_mode')();
  TextColumn get backlogStalenessJson =>
      text().named('backlog_staleness_json')();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {ownerId};
}

/// Bounded diagnostic schedule snapshots.
@DataClassName('SnapshotRow')
class Snapshots extends Table {
  TextColumn get id => text()();
  TextColumn get ownerId => text().named('owner_id')();
  DateTimeColumn get capturedAtUtc => dateTime().named('captured_at_utc')();
  TextColumn get operationName => text().named('operation_name').nullable()();
  TextColumn get sourceDate => text().named('source_date').nullable()();
  TextColumn get targetDate => text().named('target_date').nullable()();
  TextColumn get windowJson => text().named('window_json')();
  TextColumn get tasksJson => text().named('tasks_json')();
  TextColumn get lockedIntervalsJson => text().named('locked_intervals_json')();
  TextColumn get requiredVisibleIntervalsJson =>
      text().named('required_visible_intervals_json')();
  TextColumn get noticesJson => text().named('notices_json')();
  TextColumn get changesJson => text().named('changes_json')();
  TextColumn get overlapsJson => text().named('overlaps_json')();
  DateTimeColumn get retentionExpiresUtc =>
      dateTime().named('retention_expires_utc')();
  BoolColumn get truncated => boolean()();
  IntColumn get revision => integer()();
  DateTimeColumn get createdAtUtc => dateTime().named('created_at_utc')();
  DateTimeColumn get updatedAtUtc => dateTime().named('updated_at_utc')();

  @override
  Set<Column<Object>> get primaryKey => {id};
}

/// Generated task-row accessor.
@DriftAccessor(tables: [Tasks])
class TaskDao extends DatabaseAccessor<SchedulerDb> with _$TaskDaoMixin {
  TaskDao(super.db);
}

/// Generated project-row accessor.
@DriftAccessor(tables: [Projects])
class ProjectDao extends DatabaseAccessor<SchedulerDb> with _$ProjectDaoMixin {
  ProjectDao(super.db);
}

/// Generated locked-time accessors for blocks and date overrides.
@DriftAccessor(tables: [LockedBlocks, LockedOverrides])
class LockedBlockDao extends DatabaseAccessor<SchedulerDb>
    with _$LockedBlockDaoMixin {
  LockedBlockDao(super.db);
}

/// Generated owner-settings accessor.
@DriftAccessor(tables: [SettingsTable])
class SettingsDao extends DatabaseAccessor<SchedulerDb>
    with _$SettingsDaoMixin {
  SettingsDao(super.db);
}

/// Generated diagnostic snapshot accessor.
@DriftAccessor(tables: [Snapshots])
class SnapshotDao extends DatabaseAccessor<SchedulerDb>
    with _$SnapshotDaoMixin {
  SnapshotDao(super.db);
}

/// Drift database for scheduler persistence.
@DriftDatabase(
  tables: [
    Tasks,
    Projects,
    LockedBlocks,
    LockedOverrides,
    SettingsTable,
    Snapshots,
  ],
  daos: [
    TaskDao,
    ProjectDao,
    LockedBlockDao,
    SettingsDao,
    SnapshotDao,
  ],
)
class SchedulerDb extends _$SchedulerDb {
  SchedulerDb(super.executor);

  @override
  int get schemaVersion => 1;

  @override
  MigrationStrategy get migration => MigrationStrategy(
        onCreate: (Migrator migrator) async {
          await migrator.createAll();
        },
      );
}
