import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'package:household_keeper/core/notifications/notification_settings_notifier.dart';

/// Helper: create a container and wait for the initial async _load() to finish.
Future<ProviderContainer> makeContainer() async {
  final container = ProviderContainer();
  // Trigger build
  container.read(notificationSettingsProvider);
  // Allow the async _load() to complete
  await Future<void>.delayed(Duration.zero);
  return container;
}

void main() {
  setUp(() {
    SharedPreferences.setMockInitialValues({});
  });

  group('NotificationSettingsNotifier', () {
    test('build() returns default state (enabled=false, time=07:00)', () async {
      final container = ProviderContainer();
      addTearDown(container.dispose);

      final state = container.read(notificationSettingsProvider);

      expect(state.enabled, isFalse);
      expect(state.time, const TimeOfDay(hour: 7, minute: 0));
    });

    test('setEnabled(true) updates state.enabled to true', () async {
      final container = await makeContainer();
      addTearDown(container.dispose);

      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(true);

      expect(
        container.read(notificationSettingsProvider).enabled,
        isTrue,
      );
    });

    test('setEnabled(true) persists to SharedPreferences', () async {
      final container = await makeContainer();
      addTearDown(container.dispose);

      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(true);

      final prefs = await SharedPreferences.getInstance();
      expect(prefs.getBool('notifications_enabled'), isTrue);
    });

    test('setEnabled(false) updates state.enabled to false', () async {
      final container = await makeContainer();
      addTearDown(container.dispose);

      // First enable, then disable
      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(true);
      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(false);

      expect(
        container.read(notificationSettingsProvider).enabled,
        isFalse,
      );
    });

    test('setEnabled(false) persists to SharedPreferences', () async {
      final container = await makeContainer();
      addTearDown(container.dispose);

      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(true);
      await container
          .read(notificationSettingsProvider.notifier)
          .setEnabled(false);

      final prefs = await SharedPreferences.getInstance();
      expect(prefs.getBool('notifications_enabled'), isFalse);
    });

    test(
      'setTime(09:30) updates state.time and persists hour+minute',
      () async {
        final container = await makeContainer();
        addTearDown(container.dispose);

        await container
            .read(notificationSettingsProvider.notifier)
            .setTime(const TimeOfDay(hour: 9, minute: 30));

        expect(
          container.read(notificationSettingsProvider).time,
          const TimeOfDay(hour: 9, minute: 30),
        );

        final prefs = await SharedPreferences.getInstance();
        expect(prefs.getInt('notifications_hour'), 9);
        expect(prefs.getInt('notifications_minute'), 30);
      },
    );

    test(
      'After _load() with existing prefs, state reflects persisted values',
      () async {
        SharedPreferences.setMockInitialValues({
          'notifications_enabled': true,
          'notifications_hour': 8,
          'notifications_minute': 15,
        });

        final container = await makeContainer();
        addTearDown(container.dispose);

        final state = container.read(notificationSettingsProvider);
        expect(state.enabled, isTrue);
        expect(state.time, const TimeOfDay(hour: 8, minute: 15));
      },
    );
  });
}
