// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

void main() {
  group('TimeOfDay.format', () {
    testWidgets('respects alwaysUse24HourFormat option', (WidgetTester tester) async {
      Future<String> pumpTest(bool alwaysUse24HourFormat) async {
        late String formattedValue;
        await tester.pumpWidget(MaterialApp(
          home: MediaQuery(
            data: MediaQueryData(alwaysUse24HourFormat: alwaysUse24HourFormat),
            child: Builder(builder: (BuildContext context) {
              formattedValue = const TimeOfDay(hour: 7, minute: 0).format(context);
              return Container();
            }),
          ),
        ));
        return formattedValue;
      }

      expect(await pumpTest(false), '7:00 AM');
      expect(await pumpTest(true), '07:00');
    });
  });

  testWidgets('hourOfPeriod returns correct value', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/59158.
    expect(const TimeOfDay(minute: 0, hour:  0).hourOfPeriod, 12);
    expect(const TimeOfDay(minute: 0, hour:  1).hourOfPeriod,  1);
    expect(const TimeOfDay(minute: 0, hour:  2).hourOfPeriod,  2);
    expect(const TimeOfDay(minute: 0, hour:  3).hourOfPeriod,  3);
    expect(const TimeOfDay(minute: 0, hour:  4).hourOfPeriod,  4);
    expect(const TimeOfDay(minute: 0, hour:  5).hourOfPeriod,  5);
    expect(const TimeOfDay(minute: 0, hour:  6).hourOfPeriod,  6);
    expect(const TimeOfDay(minute: 0, hour:  7).hourOfPeriod,  7);
    expect(const TimeOfDay(minute: 0, hour:  8).hourOfPeriod,  8);
    expect(const TimeOfDay(minute: 0, hour:  9).hourOfPeriod,  9);
    expect(const TimeOfDay(minute: 0, hour: 10).hourOfPeriod, 10);
    expect(const TimeOfDay(minute: 0, hour: 11).hourOfPeriod, 11);
    expect(const TimeOfDay(minute: 0, hour: 12).hourOfPeriod, 12);
    expect(const TimeOfDay(minute: 0, hour: 13).hourOfPeriod,  1);
    expect(const TimeOfDay(minute: 0, hour: 14).hourOfPeriod,  2);
    expect(const TimeOfDay(minute: 0, hour: 15).hourOfPeriod,  3);
    expect(const TimeOfDay(minute: 0, hour: 16).hourOfPeriod,  4);
    expect(const TimeOfDay(minute: 0, hour: 17).hourOfPeriod,  5);
    expect(const TimeOfDay(minute: 0, hour: 18).hourOfPeriod,  6);
    expect(const TimeOfDay(minute: 0, hour: 19).hourOfPeriod,  7);
    expect(const TimeOfDay(minute: 0, hour: 20).hourOfPeriod,  8);
    expect(const TimeOfDay(minute: 0, hour: 21).hourOfPeriod,  9);
    expect(const TimeOfDay(minute: 0, hour: 22).hourOfPeriod, 10);
    expect(const TimeOfDay(minute: 0, hour: 23).hourOfPeriod, 11);
  });

  group('RestorableTimeOfDay tests', () {
    testWidgets('value is not accessible when not registered', (WidgetTester tester) async {
      expect(() => RestorableTimeOfDay(const TimeOfDay(hour: 20, minute: 4)).value, throwsAssertionError);
    });

    testWidgets('work when not in restoration scope', (WidgetTester tester) async {
      await tester.pumpWidget(const _RestorableWidget());

      final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

      // Initialized to default values.
      expect(state.timeOfDay.value, const TimeOfDay(hour: 10, minute: 5));

      // Modify values.
      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 2, minute: 2);
      });
      await tester.pump();

      expect(state.timeOfDay.value, const TimeOfDay(hour: 2, minute: 2));
    });

    testWidgets('restart and restore', (WidgetTester tester) async {
      await tester.pumpWidget(const RootRestorationScope(
        restorationId: 'root-child',
        child: _RestorableWidget(),
      ));

      _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

      // Initialized to default values.
      expect(state.timeOfDay.value, const TimeOfDay(hour: 10, minute: 5));

      // Modify values.
      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 2, minute: 2);
      });
      await tester.pump();

      expect(state.timeOfDay.value, const TimeOfDay(hour: 2, minute: 2));

      // Restores to previous values.
      await tester.restartAndRestore();
      final _RestorableWidgetState oldState = state;
      state = tester.state(find.byType(_RestorableWidget));
      expect(state, isNot(same(oldState)));

      expect(state.timeOfDay.value, const TimeOfDay(hour: 2, minute: 2));
    });

    testWidgets('restore to older state', (WidgetTester tester) async {
      await tester.pumpWidget(const RootRestorationScope(
        restorationId: 'root-child',
        child: _RestorableWidget(),
      ));

      final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

      // Modify values.
      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 2, minute: 2);
      });
      await tester.pump();

      final TestRestorationData restorationData = await tester.getRestorationData();

      // Modify values.
      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 4, minute: 4);
      });
      await tester.pump();

      // Restore to previous.
      await tester.restoreFrom(restorationData);
      expect(state.timeOfDay.value, const TimeOfDay(hour: 2, minute: 2));

      // Restore to empty data will re-initialize to default values.
      await tester.restoreFrom(TestRestorationData.empty);
      expect(state.timeOfDay.value, const TimeOfDay(hour: 10, minute: 5));
    });

    testWidgets('call notifiers when value changes', (WidgetTester tester) async {
      await tester.pumpWidget(const RootRestorationScope(
        restorationId: 'root-child',
        child: _RestorableWidget(),
      ));

      final _RestorableWidgetState state = tester.state(find.byType(_RestorableWidget));

      final List<String> notifyLog = <String>[];

      state.timeOfDay.addListener(() {
        notifyLog.add('hello world');
      });

      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 2, minute: 2);
      });
      expect(notifyLog.single, 'hello world');
      notifyLog.clear();
      await tester.pump();

      // Does not notify when set to same value.
      state.setProperties(() {
        state.timeOfDay.value = const TimeOfDay(hour: 2, minute: 2);
      });

      expect(notifyLog, isEmpty);
    });
  });
}

class _RestorableWidget extends StatefulWidget {
  const _RestorableWidget({Key? key}) : super(key: key);

  @override
  State<_RestorableWidget> createState() => _RestorableWidgetState();
}

class _RestorableWidgetState extends State<_RestorableWidget> with RestorationMixin {
  final RestorableTimeOfDay timeOfDay = RestorableTimeOfDay(const TimeOfDay(hour: 10, minute: 5));

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    registerForRestoration(timeOfDay, 'time_of_day');
  }

  void setProperties(VoidCallback callback) {
    setState(callback);
  }

  @override
  Widget build(BuildContext context) {
    return const SizedBox();
  }

  @override
  String get restorationId => 'widget';
}
