// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../../scheduler_db.dart';

/// Drift database for scheduler persistence.
@DriftDatabase(
  tables: [
    Tasks,
    TaskActivities,
    Projects,
    ProjectStatisticsTable,
    LockedBlocks,
    LockedOverrides,
    SettingsTable,
    Snapshots,
    ApplicationOperations,
    NoticeAcknowledgements,
  ],
  daos: [
    TaskDao,
    ProjectDao,
    LockedBlockDao,
    SettingsDao,
    SnapshotDao,
  ],
)
class SchedulerDb extends _$SchedulerDb {
  /// Creates a `SchedulerDb` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  SchedulerDb(super.executor);

  /// Returns the derived `schemaVersion` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  @override
  int get schemaVersion => 2;

  /// Runs the `migration` operation and completes after its asynchronous work finishes.
  /// Callers should await the returned future so repository writes, UI refreshes, and failure handling happen in a predictable order.
  @override
  MigrationStrategy get migration => MigrationStrategy(
        onCreate: (Migrator migrator) async {
          await migrator.createAll();
          await _createApplicationIndexes();
        },
        onUpgrade: (Migrator migrator, int from, int to) async {
          if (from < 2) {
            await migrator.createTable(taskActivities);
            await migrator.createTable(projectStatisticsTable);
            await migrator.createTable(applicationOperations);
            await migrator.createTable(noticeAcknowledgements);
            await _createApplicationIndexes();
          }
        },
      );

  /// Creates secondary indexes for app-layer tables.
  Future<void> _createApplicationIndexes() async {
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_application_operations_owner '
      'ON application_operations(owner_id)',
    );
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_task_activities_owner '
      'ON task_activities(owner_id)',
    );
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_task_activities_task '
      'ON task_activities(task_id)',
    );
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_task_activities_project '
      'ON task_activities(project_id)',
    );
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_task_activities_operation '
      'ON task_activities(operation_id)',
    );
    await customStatement(
      'CREATE UNIQUE INDEX IF NOT EXISTS idx_project_statistics_owner_project '
      'ON project_statistics(owner_id, project_id)',
    );
    await customStatement(
      'CREATE INDEX IF NOT EXISTS idx_notice_acknowledgements_owner '
      'ON notice_acknowledgements(owner_id)',
    );
  }
}
