import 'dart:developer';

import 'package:localstore/localstore.dart';

import '../../../../model/account_data.dart';
import '../../../demo/demo_mode.dart';
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event.dart';
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event_params.dart';
import '../../../mhsl/custom_timetable_event/remove/remove_custom_timetable_event.dart';
import '../../../mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.dart';
import 'timetable_custom_events_add.dart';

/// One-time migration of the user's custom timetable events from the legacy
/// MHSL backend to Marianum-Connect. Runs at most once per install, guarded by
/// a persisted flag.
///
/// The MHSL identity is `sha512(username:password)` — computed here exactly as
/// the app always did, so the fetch matches the user's own events perfectly.
/// Each event is POSTed to Marianum-Connect and then deleted from MHSL, which
/// makes the whole run idempotent and resumable: a re-run after a mid-way
/// failure only sees the events that were not yet moved, so nothing is
/// duplicated. The flag is set only once MHSL reports no remaining events.
class CustomEventsMigration {
  static const String _collection = 'MarianumMobile';
  static const String _document = 'customEventsMigration';
  static const String _doneKey = 'migratedToMc';

  const CustomEventsMigration._();

  static Future<void> runOnce() async {
    if (DemoMode.active) return;
    if (await _isDone()) return;

    try {
      final response = await GetCustomTimetableEvent(
        GetCustomTimetableEventParams(AccountData().getUserSecret()),
      ).run();

      for (final event in response.events) {
        await TimetableCustomEventsAdd().run(event);
        await RemoveCustomTimetableEvent(
          RemoveCustomTimetableEventParams(event.id),
        ).run();
      }

      await _markDone();
      log('Custom events migration: moved ${response.events.length} event(s) to Marianum-Connect.');
    } catch (e) {
      // Leave the flag unset so the next launch retries; the delete-after-post
      // above keeps a partial run duplicate-free.
      log('Custom events migration failed, will retry on next launch: $e');
    }
  }

  static Future<bool> _isDone() async {
    final data = await Localstore.instance
        .collection(_collection)
        .doc(_document)
        .get();
    return data != null && data[_doneKey] == true;
  }

  static Future<void> _markDone() async {
    await Localstore.instance.collection(_collection).doc(_document).set({
      _doneKey: true,
    });
  }
}
