import 'dart:io';

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:health_app/providers/chat_provider.dart';

void main() {
  test('chat state can clear a loaded conversation id for a new chat', () {
    const state = ChatState(conversationId: 'old-conversation');

    final next = state.copyWith(conversationId: null);

    expect(next.conversationId, isNull);
  });

  test('history continues with the same conversation and visible context', () {
    final chatSource = File(
      'lib/providers/chat_provider.dart',
    ).readAsStringSync();

    expect(chatSource, contains('conversationId: convId'));
    expect(
      chatSource,
      isNot(
        contains(
          'state = const ChatState();\n  }\n\n'
          '  Future<void> _cancelActiveStream()',
        ),
      ),
    );
  });

  test('delayed agent welcome is skipped after session reset', () async {
    final container = ProviderContainer();
    addTearDown(container.dispose);

    final notifier = container.read(chatProvider.notifier);
    notifier.triggerAgent(ActiveAgent.diet, '营养助手');
    await notifier.resetSession();

    await Future<void>.delayed(const Duration(milliseconds: 450));

    final messages = container.read(chatProvider).messages;
    expect(messages, isEmpty);
  });

  test('agent capsule inserts welcome immediately', () {
    final container = ProviderContainer();
    addTearDown(container.dispose);

    container
        .read(chatProvider.notifier)
        .triggerAgent(ActiveAgent.diet, '营养助手');

    final messages = container.read(chatProvider).messages;
    expect(messages.map((m) => m.type), contains(MessageType.agentWelcome));
    expect(container.read(chatProvider).activeAgent, ActiveAgent.diet);
  });

  test(
    'pending agent capsule ignores later taps until welcome appears',
    () async {
      final container = ProviderContainer();
      addTearDown(container.dispose);

      final notifier = container.read(chatProvider.notifier);
      notifier.triggerAgent(ActiveAgent.diet, '营养助手');
      notifier.triggerAgent(ActiveAgent.medication, '药管家');

      final welcomeAgents = container
          .read(chatProvider)
          .messages
          .where((m) => m.type == MessageType.agentWelcome)
          .map((m) => m.metadata?['agent'])
          .toList();

      expect(welcomeAgents, ['diet']);
      expect(container.read(chatProvider).activeAgent, ActiveAgent.diet);
    },
  );

  test('repeated tap on the same agent does not add another card', () async {
    final container = ProviderContainer();
    addTearDown(container.dispose);

    final notifier = container.read(chatProvider.notifier);
    notifier.triggerAgent(ActiveAgent.diet, '营养助手');
    notifier.triggerAgent(ActiveAgent.diet, '营养助手');

    expect(
      container
          .read(chatProvider)
          .messages
          .where((message) => message.type == MessageType.agentWelcome)
          .length,
      1,
    );
  });

  test(
    'different agent is accepted after the previous welcome appears',
    () async {
      final container = ProviderContainer();
      addTearDown(container.dispose);

      final notifier = container.read(chatProvider.notifier);
      notifier.triggerAgent(ActiveAgent.diet, '营养助手');
      await Future<void>.delayed(const Duration(milliseconds: 320));
      notifier.triggerAgent(ActiveAgent.medication, '药管家');

      expect(
        container
            .read(chatProvider)
            .messages
            .where((message) => message.type == MessageType.agentWelcome)
            .map((message) => message.metadata?['agent']),
        ['diet', 'medication'],
      );
    },
  );
}
