import 'package:commons_core/commons_core.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:tane/domain/chat_timeline.dart';

void main() {
  // In the app, flutter_localizations loads intl's locale symbols; a pure test
  // must initialize them itself before any DateFormat.
  setUpAll(initializeDateFormatting);

  PrivateMessage at(DateTime when) =>
      PrivateMessage(fromPubkey: 'p', text: 't', at: when);

  group('chatTimeline', () {
    test('empty in, empty out', () {
      expect(chatTimeline(const []), isEmpty);
    });

    test('a day separator precedes the first message of each day', () {
      final items = chatTimeline([
        at(DateTime(2026, 6, 14, 10)),
        at(DateTime(2026, 6, 14, 11)),
        at(DateTime(2026, 6, 15, 9)),
      ]);
      // sep, msg, msg, sep, msg
      expect(items.map((i) => i is ChatDaySeparator), [
        true,
        false,
        false,
        true,
        false,
      ]);
      expect((items[0] as ChatDaySeparator).day, DateTime(2026, 6, 14));
      expect((items[3] as ChatDaySeparator).day, DateTime(2026, 6, 15));
    });

    test('messages stay oldest-first', () {
      final items = chatTimeline([
        at(DateTime(2026, 1, 1, 8)),
        at(DateTime(2026, 1, 1, 9)),
      ]);
      expect(items.whereType<ChatMessageRow>(), hasLength(2));
      expect(items.whereType<ChatDaySeparator>(), hasLength(1));
    });
  });

  group('chatDayLabel', () {
    final now = DateTime(2026, 6, 15, 12);

    test('the two most recent days use the given today/yesterday labels', () {
      expect(
        chatDayLabel(
          DateTime(2026, 6, 15),
          now: now,
          today: 'Today',
          yesterday: 'Yesterday',
          localeCode: 'en',
        ),
        'Today',
      );
      expect(
        chatDayLabel(
          DateTime(2026, 6, 14),
          now: now,
          today: 'Today',
          yesterday: 'Yesterday',
          localeCode: 'en',
        ),
        'Yesterday',
      );
    });

    test('older days use a locale date, not today/yesterday', () {
      final label = chatDayLabel(
        DateTime(2026, 6, 10),
        now: now,
        today: 'Today',
        yesterday: 'Yesterday',
        localeCode: 'en',
      );
      expect(label, isNot(anyOf('Today', 'Yesterday')));
      expect(label, contains('10')); // the day number
    });

    test('a previous year is shown', () {
      final label = chatDayLabel(
        DateTime(2024, 6, 10),
        now: now,
        today: 'Today',
        yesterday: 'Yesterday',
        localeCode: 'en',
      );
      expect(label, contains('2024'));
    });

    test('respects the locale (Spanish month name)', () {
      final label = chatDayLabel(
        DateTime(2026, 6, 10),
        now: now,
        today: 'Hoy',
        yesterday: 'Ayer',
        localeCode: 'es',
      );
      expect(label.toLowerCase(), contains('junio'));
    });
  });

  group('chatBubbleTime', () {
    test('English uses a 12-hour clock', () {
      final s = chatBubbleTime(DateTime(2026, 1, 1, 14, 5), 'en');
      expect(s.toUpperCase(), contains('PM'));
    });

    test('Spanish uses a 24-hour clock', () {
      final s = chatBubbleTime(DateTime(2026, 1, 1, 14, 5), 'es');
      expect(s, contains('14'));
      expect(s.toUpperCase(), isNot(contains('PM')));
    });
  });
}
