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

part of '../sqlite_repositories.dart';

/// SQLite implementation of the app-layer owner settings repository.
final class _SqliteApplicationOwnerSettingsRepository
    implements core.OwnerSettingsRepository {
  /// Creates an owner settings repository for [db].
  _SqliteApplicationOwnerSettingsRepository(this.db);

  /// Shared SQLite database handle.
  final SchedulerDb db;

  /// Returns settings for [ownerId].
  @override
  Future<core.OwnerSettings?> findByOwnerId(String ownerId) async {
    final row = await _settingsByOwnerId(ownerId);
    return row == null ? null : _settingsFromRow(row);
  }

  /// Returns settings plus owner/revision metadata.
  @override
  Future<core.RepositoryRecord<core.OwnerSettings>?> findRecordByOwnerId(
    String ownerId,
  ) async {
    final row = await _settingsByOwnerId(ownerId);
    if (row == null) {
      return null;
    }
    return core.RepositoryRecord(
      value: _settingsFromRow(row),
      ownerId: row.ownerId,
      revision: row.revision,
    );
  }

  /// Saves [settings], inserting it when absent.
  @override
  Future<void> save(core.OwnerSettings settings) async {
    final row = await _settingsByOwnerId(settings.ownerId);
    if (row == null) {
      await db.into(db.settingsTable).insert(
            _settingsCompanion(
              settings,
              revision: core.Revision.initial,
              createdAt: _epoch,
              updatedAt: _epoch,
            ),
          );
      return;
    }
    await (db.update(db.settingsTable)
          ..where((table) => table.ownerId.equals(settings.ownerId)))
        .write(
      _settingsCompanion(
        settings,
        revision: core.Revision(row.revision).next(),
        createdAt: row.createdAtUtc,
        updatedAt: _epoch,
      ),
    );
  }

  /// Saves [settings] only when the repository revision matches [expectedRevision].
  @override
  Future<core.RepositoryMutationResult> saveIfRevision({
    required core.OwnerSettings settings,
    required int expectedRevision,
  }) async {
    final row = await _settingsByOwnerId(settings.ownerId);
    final failure = _compareForWrite(
      row: row,
      ownerId: settings.ownerId,
      expectedRevision: expectedRevision,
      entityId: settings.ownerId,
      rowOwnerId: row?.ownerId,
      rowRevision: row?.revision,
    );
    if (failure != null) {
      return failure;
    }
    final nextRevision = core.Revision(expectedRevision).next();
    await (db.update(db.settingsTable)
          ..where(
            (table) =>
                table.ownerId.equals(settings.ownerId) &
                table.revision.equals(expectedRevision),
          ))
        .write(
      _settingsCompanion(
        settings,
        revision: nextRevision,
        createdAt: row!.createdAtUtc,
        updatedAt: _epoch,
      ),
    );
    return core.RepositoryMutationResult.success(revision: nextRevision.value);
  }

  /// Returns a raw settings row by owner id.
  Future<SettingsRow?> _settingsByOwnerId(String ownerId) {
    return (db.select(db.settingsTable)
          ..where((table) => table.ownerId.equals(ownerId)))
        .getSingleOrNull();
  }
}
